From 405dca5bb45ba23f58020b35cba5f6d2f68da033 Mon Sep 17 00:00:00 2001 From: zipg Date: Fri, 24 Jul 2026 09:31:31 +0800 Subject: [PATCH] fix(kingbase): restore column comments in table DDL --- .../drivers/kingbase-go/integration_test.go | 21 ++++++++++++ .../drivers/kingbase-go/kingbase_metadata.go | 18 ++++++++++- agents/drivers/kingbase-go/main_test.go | 32 +++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/agents/drivers/kingbase-go/integration_test.go b/agents/drivers/kingbase-go/integration_test.go index 352a20bb1..abeaecbb6 100644 --- a/agents/drivers/kingbase-go/integration_test.go +++ b/agents/drivers/kingbase-go/integration_test.go @@ -54,6 +54,9 @@ func TestKingbaseIntegration(t *testing.T) { }) mustExecute(t, server, "CREATE TABLE public."+quoteIdentifier(parent)+" (id integer PRIMARY KEY, name varchar(64) NOT NULL)") + mustExecute(t, server, "COMMENT ON TABLE public."+quoteIdentifier(parent)+" IS '订单父表'") + mustExecute(t, server, "COMMENT ON COLUMN public."+quoteIdentifier(parent)+".id IS '主键编号'") + mustExecute(t, server, "COMMENT ON COLUMN public."+quoteIdentifier(parent)+".name IS '客户''名称'") mustExecute(t, server, "CREATE TABLE public."+quoteIdentifier(child)+" (id integer PRIMARY KEY, parent_id integer REFERENCES public."+quoteIdentifier(parent)+"(id))") mustExecute(t, server, "CREATE INDEX "+quoteIdentifier(child+"_parent_idx")+" ON public."+quoteIdentifier(child)+"(parent_id)") mustExecute(t, server, "CREATE VIEW public."+quoteIdentifier(view)+" AS SELECT id, name FROM public."+quoteIdentifier(parent)) @@ -67,6 +70,24 @@ func TestKingbaseIntegration(t *testing.T) { if err != nil || len(columns) != 2 || !columns[0].IsPrimaryKey { t.Fatalf("get columns failed: columns=%v err=%v", columns, err) } + parentColumns, err := server.getColumns("public", parent) + if err != nil || len(parentColumns) != 2 || parentColumns[0].Comment == nil || *parentColumns[0].Comment != "主键编号" || parentColumns[1].Comment == nil || *parentColumns[1].Comment != "客户'名称" { + t.Fatalf("get commented columns failed: columns=%v err=%v", parentColumns, err) + } + ddl, err := server.getTableDDL("public", parent) + if err != nil { + t.Fatalf("get table DDL failed: %v", err) + } + qualifiedParent := quoteIdentifier("public") + "." + quoteIdentifier(parent) + for _, expected := range []string{ + "COMMENT ON TABLE " + qualifiedParent + " IS '订单父表';", + "COMMENT ON COLUMN " + qualifiedParent + "." + quoteIdentifier("id") + " IS '主键编号';", + "COMMENT ON COLUMN " + qualifiedParent + "." + quoteIdentifier("name") + " IS '客户''名称';", + } { + if !strings.Contains(ddl, expected) { + t.Fatalf("table DDL missing %q:\n%s", expected, ddl) + } + } indexes, err := server.listIndexes("public", child) if err != nil || len(indexes) < 2 { t.Fatalf("list indexes failed: indexes=%v err=%v", indexes, err) diff --git a/agents/drivers/kingbase-go/kingbase_metadata.go b/agents/drivers/kingbase-go/kingbase_metadata.go index f0cf89b4f..4446859fb 100644 --- a/agents/drivers/kingbase-go/kingbase_metadata.go +++ b/agents/drivers/kingbase-go/kingbase_metadata.go @@ -672,6 +672,11 @@ func (s *server) getTableDDL(schema, table string) (string, error) { if err != nil { return "", err } + tableComment, _ := s.getTableComment(effective, table) + return renderTableDDL(effective, table, columns, tableComment), nil +} + +func renderTableDDL(schema, table string, columns []columnInfo, tableComment *string) string { definitions := make([]string, 0, len(columns)+1) primary := []string{} for _, column := range columns { @@ -683,7 +688,18 @@ func (s *server) getTableDDL(schema, table string) (string, error) { if len(primary) > 0 { definitions = append(definitions, "PRIMARY KEY ("+strings.Join(primary, ", ")+")") } - return "CREATE TABLE " + quoteIdentifier(effective) + "." + quoteIdentifier(table) + " (\n " + strings.Join(definitions, ",\n ") + "\n);", nil + qualifiedTable := quoteIdentifier(schema) + "." + quoteIdentifier(table) + ddl := "CREATE TABLE " + qualifiedTable + " (\n " + strings.Join(definitions, ",\n ") + "\n);" + if tableComment != nil && strings.TrimSpace(*tableComment) != "" { + ddl += "\nCOMMENT ON TABLE " + qualifiedTable + " IS " + quoteLiteral(*tableComment) + ";" + } + for _, column := range columns { + if column.Comment == nil || strings.TrimSpace(*column.Comment) == "" { + continue + } + ddl += "\nCOMMENT ON COLUMN " + qualifiedTable + "." + quoteIdentifier(column.Name) + " IS " + quoteLiteral(*column.Comment) + ";" + } + return ddl } func columnDDLDefinition(column columnInfo) string { diff --git a/agents/drivers/kingbase-go/main_test.go b/agents/drivers/kingbase-go/main_test.go index 47f2bead8..e6f114ce1 100644 --- a/agents/drivers/kingbase-go/main_test.go +++ b/agents/drivers/kingbase-go/main_test.go @@ -416,6 +416,38 @@ func TestTableDDLIncludesCatalogIdentityClause(t *testing.T) { if !strings.Contains(ddl, `"id" integer GENERATED BY DEFAULT AS IDENTITY NOT NULL`) { t.Fatalf("identity clause missing from table DDL: %s", ddl) } + if !strings.Contains(ddl, `COMMENT ON TABLE "public"."orders" IS 'orders table';`) { + t.Fatalf("table comment missing from table DDL: %s", ddl) + } +} + +func TestRenderTableDDLIncludesEscapedComments(t *testing.T) { + primaryComment := "主键'编号" + emptyComment := " " + tableComment := "订单'表" + ddl := renderTableDDL( + `app"schema`, + `order"items`, + []columnInfo{ + {Name: `id"value`, DataType: "integer", IsNullable: false, IsPrimaryKey: true, Comment: &primaryComment}, + {Name: "note", DataType: "text", IsNullable: true, Comment: &emptyComment}, + }, + &tableComment, + ) + + expected := []string{ + `CREATE TABLE "app""schema"."order""items"`, + `COMMENT ON TABLE "app""schema"."order""items" IS '订单''表';`, + `COMMENT ON COLUMN "app""schema"."order""items"."id""value" IS '主键''编号';`, + } + for _, fragment := range expected { + if !strings.Contains(ddl, fragment) { + t.Fatalf("table DDL missing %q:\n%s", fragment, ddl) + } + } + if strings.Contains(ddl, `COMMENT ON COLUMN "app""schema"."order""items"."note"`) { + t.Fatalf("blank column comment must be omitted:\n%s", ddl) + } } func TestColumnDDLDefinitionPreservesCompatibilityExtras(t *testing.T) {