🐛 fix(kingbase): 修复表操作标识符引用

This commit is contained in:
Syngnat
2026-04-28 10:21:19 +08:00
parent fa4f2a938a
commit 225e9e61ed
5 changed files with 76 additions and 0 deletions

View File

@@ -49,3 +49,16 @@ func TestNormalizeSchemaAndTable_PostgresStillSplitsQualifiedName(t *testing.T)
t.Fatalf("expected postgres qualified split to public.orders, got %q.%q", schema, table)
}
}
func TestQuoteTableIdentByType_KingbaseNormalizesQuotedQualifiedTable(t *testing.T) {
t.Parallel()
schema, table := normalizeSchemaAndTableByType("kingbase", "", `\"Idf_server\".\"mes_bip_wip_finished\"`)
if schema != "Idf_server" || table != "mes_bip_wip_finished" {
t.Fatalf("expected kingbase qualified split to Idf_server.mes_bip_wip_finished, got %q.%q", schema, table)
}
if got := quoteTableIdentByType("kingbase", schema, table); got != `"Idf_server"."mes_bip_wip_finished"` {
t.Fatalf("unexpected kingbase table identifier: %s", got)
}
}

View File

@@ -174,6 +174,16 @@ func normalizeSchemaAndTableByType(dbType string, dbName string, tableName strin
return rawDB, rawTable
}
if dbType == "kingbase" {
schema, table := db.SplitKingbaseQualifiedName(rawTable)
if schema != "" && table != "" {
return schema, table
}
if table != "" {
return "public", table
}
}
if parts := strings.SplitN(rawTable, ".", 2); len(parts) == 2 {
schema := strings.TrimSpace(parts[0])
table := strings.TrimSpace(parts[1])

View File

@@ -1328,6 +1328,12 @@ func quoteIdentByType(dbType string, ident string) string {
switch dbType {
case "mysql", "mariadb", "diros", "sphinx", "tdengine", "clickhouse":
return "`" + strings.ReplaceAll(ident, "`", "``") + "`"
case "kingbase":
cleaned := db.NormalizeKingbaseIdentifier(ident)
if cleaned == "" {
return `""`
}
return `"` + strings.ReplaceAll(cleaned, `"`, `""`) + `"`
case "sqlserver":
escaped := strings.ReplaceAll(ident, "]", "]]")
return "[" + escaped + "]"
@@ -1342,6 +1348,17 @@ func quoteQualifiedIdentByType(dbType string, ident string) string {
return raw
}
if dbType == "kingbase" {
schema, table := db.SplitKingbaseQualifiedName(raw)
if table == "" {
return quoteIdentByType(dbType, raw)
}
if schema == "" {
return quoteIdentByType(dbType, table)
}
return quoteIdentByType(dbType, schema) + "." + quoteIdentByType(dbType, table)
}
parts := strings.Split(raw, ".")
if len(parts) <= 1 {
return quoteIdentByType(dbType, raw)

View File

@@ -46,6 +46,32 @@ func TestBuildTableDataClearSQL_ClearUsesMongoDeleteCommand(t *testing.T) {
}
}
func TestBuildTableDataClearSQL_KingbaseTruncateNormalizesQuotedQualifiedTable(t *testing.T) {
t.Parallel()
sql, err := buildTableDataClearSQL(connection.ConnectionConfig{Type: "kingbase"}, `\"Idf_server\".\"mes_bip_wip_finished\"`, tableDataClearModeTruncate)
if err != nil {
t.Fatalf("buildTableDataClearSQL() unexpected error: %v", err)
}
if sql != `TRUNCATE TABLE "Idf_server"."mes_bip_wip_finished"` {
t.Fatalf("unexpected kingbase truncate sql: %s", sql)
}
}
func TestBuildTableDataClearSQL_KingbaseClearNormalizesQuotedQualifiedTable(t *testing.T) {
t.Parallel()
sql, err := buildTableDataClearSQL(connection.ConnectionConfig{Type: "kingbase"}, `\"Idf_server\".\"mes_bip_wip_finished\"`, tableDataClearModeDeleteAll)
if err != nil {
t.Fatalf("buildTableDataClearSQL() unexpected error: %v", err)
}
if sql != `DELETE FROM "Idf_server"."mes_bip_wip_finished"` {
t.Fatalf("unexpected kingbase clear sql: %s", sql)
}
}
func TestBuildTableDataClearSQL_TruncateRejectsUnsupportedDialect(t *testing.T) {
t.Parallel()

View File

@@ -78,6 +78,16 @@ func normalizeKingbaseIdentCommon(raw string) string {
return strings.TrimSpace(value)
}
// NormalizeKingbaseIdentifier removes nested client-side quoting from a Kingbase identifier.
func NormalizeKingbaseIdentifier(raw string) string {
return normalizeKingbaseIdentCommon(raw)
}
// SplitKingbaseQualifiedName splits a Kingbase schema-qualified identifier safely.
func SplitKingbaseQualifiedName(raw string) (schema string, table string) {
return splitKingbaseQualifiedNameCommon(raw)
}
func splitKingbaseQualifiedNameCommon(raw string) (schema string, table string) {
text := strings.TrimSpace(raw)
if text == "" {