diff --git a/frontend/package.json.md5 b/frontend/package.json.md5 index a7661c00..0f8f4fed 100755 --- a/frontend/package.json.md5 +++ b/frontend/package.json.md5 @@ -1 +1 @@ -d0f9366af59a6367ad3c7e2d4185ead4 \ No newline at end of file +5b8157374dae5f9340e31b2d0bd2c00e \ No newline at end of file diff --git a/internal/db/kingbase_identifier_utils.go b/internal/db/kingbase_identifier_utils.go index f3412acc..09e8a1e9 100644 --- a/internal/db/kingbase_identifier_utils.go +++ b/internal/db/kingbase_identifier_utils.go @@ -162,3 +162,45 @@ func findKingbaseQualifiedSeparator(raw string) int { return -1 } + +// buildKingbaseSearchPathCommon 统一构建 Kingbase search_path。 +// 返回 search_path SQL 片段和规范化后的 schema 列表(用于调试/扩展)。 +func buildKingbaseSearchPathCommon(rawSchemas []string) (string, []string) { + if len(rawSchemas) == 0 { + return "", nil + } + + seen := make(map[string]struct{}, len(rawSchemas)+1) + quotedParts := make([]string, 0, len(rawSchemas)+1) + normalizedSchemas := make([]string, 0, len(rawSchemas)+1) + + appendSchema := func(raw string) { + cleaned := normalizeKingbaseIdentCommon(raw) + if cleaned == "" { + return + } + if strings.EqualFold(cleaned, "public") { + cleaned = "public" + } + key := strings.ToLower(cleaned) + if _, ok := seen[key]; ok { + return + } + seen[key] = struct{}{} + normalizedSchemas = append(normalizedSchemas, cleaned) + escaped := strings.ReplaceAll(cleaned, `"`, `""`) + quotedParts = append(quotedParts, `"`+escaped+`"`) + } + + for _, raw := range rawSchemas { + appendSchema(raw) + } + if _, ok := seen["public"]; !ok { + appendSchema("public") + } + + if len(quotedParts) == 0 { + return "", normalizedSchemas + } + return strings.Join(quotedParts, ", "), normalizedSchemas +} diff --git a/internal/db/kingbase_identifier_utils_test.go b/internal/db/kingbase_identifier_utils_test.go index 69e2b2e9..7e8cec85 100644 --- a/internal/db/kingbase_identifier_utils_test.go +++ b/internal/db/kingbase_identifier_utils_test.go @@ -50,3 +50,43 @@ func TestSplitKingbaseQualifiedNameCommon(t *testing.T) { }) } } + +func TestBuildKingbaseSearchPathCommon(t *testing.T) { + tests := []struct { + name string + in []string + want string + wantLen int + }{ + { + name: "normal schemas", + in: []string{"ldf_server", "public"}, + want: `"ldf_server", "public"`, + wantLen: 2, + }, + { + name: "quoted and escaped schemas should not be double quoted", + in: []string{`"ldf_server"`, `""bcs_barcode""`, `\"public\"`}, + want: `"ldf_server", "bcs_barcode", "public"`, + wantLen: 3, + }, + { + name: "dedupe ignoring case and keep public fallback", + in: []string{"LDF_SERVER", "ldf_server", "PUBLIC"}, + want: `"LDF_SERVER", "public"`, + wantLen: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, parts := buildKingbaseSearchPathCommon(tt.in) + if got != tt.want { + t.Fatalf("buildKingbaseSearchPathCommon(%v)=%q,want=%q", tt.in, got, tt.want) + } + if len(parts) != tt.wantLen { + t.Fatalf("buildKingbaseSearchPathCommon(%v) parts=%v, len=%d, wantLen=%d", tt.in, parts, len(parts), tt.wantLen) + } + }) + } +} diff --git a/internal/db/kingbase_impl.go b/internal/db/kingbase_impl.go index d4eda202..77a4ac35 100644 --- a/internal/db/kingbase_impl.go +++ b/internal/db/kingbase_impl.go @@ -198,7 +198,7 @@ func (k *KingbaseDB) getSearchPathStr() string { } defer rows.Close() - var schemas []string + var rawSchemas []string for rows.Next() { var name string if err := rows.Scan(&name); err != nil { @@ -206,17 +206,12 @@ func (k *KingbaseDB) getSearchPathStr() string { } name = strings.TrimSpace(name) if name != "" { - // 使用 SQL 标准的双引号包裹标识符 - escaped := strings.ReplaceAll(name, `"`, `""`) - schemas = append(schemas, `"`+escaped+`"`) + rawSchemas = append(rawSchemas, name) } } - if len(schemas) == 0 { - return "" - } - - return strings.Join(schemas, ", ") + searchPath, _ := buildKingbaseSearchPathCommon(rawSchemas) + return searchPath } func (k *KingbaseDB) Close() error { diff --git a/internal/db/optional_driver_agent_impl.go b/internal/db/optional_driver_agent_impl.go index 07fd7d38..9316a1bd 100644 --- a/internal/db/optional_driver_agent_impl.go +++ b/internal/db/optional_driver_agent_impl.go @@ -582,27 +582,8 @@ func (d *OptionalDriverAgentDB) listKingbaseSchemas(ctx context.Context) ([]stri } func buildKingbaseSearchPathFromSchemas(schemas []string) string { - if len(schemas) == 0 { - return "" - } - seen := make(map[string]struct{}, len(schemas)+1) - parts := make([]string, 0, len(schemas)+1) - for _, name := range schemas { - trimmed := normalizeKingbaseAgentIdent(name) - if trimmed == "" { - continue - } - key := strings.ToLower(trimmed) - if _, ok := seen[key]; ok { - continue - } - seen[key] = struct{}{} - parts = append(parts, quoteKingbaseAgentIdent(trimmed)) - } - if _, ok := seen["public"]; !ok { - parts = append(parts, "public") - } - return strings.Join(parts, ", ") + searchPath, _ := buildKingbaseSearchPathCommon(schemas) + return searchPath } func quoteKingbaseAgentIdent(name string) string {