diff --git a/agents/drivers/kingbase-go/kingbase_metadata.go b/agents/drivers/kingbase-go/kingbase_metadata.go index 51381ee39..c57e976d5 100644 --- a/agents/drivers/kingbase-go/kingbase_metadata.go +++ b/agents/drivers/kingbase-go/kingbase_metadata.go @@ -215,13 +215,27 @@ func (s *server) listDatabases() ([]databaseInfo, error) { return []databaseInfo{{Name: s.params.Database}}, nil } -func (s *server) listSchemas(visible []string) ([]string, error) { - query := "SELECT nspname FROM sys_catalog.sys_namespace WHERE nspname NOT LIKE 'sys_temp_%' AND nspname NOT LIKE 'sys_toast_temp_%' ORDER BY nspname" - if s.mode.postgresCatalog { - query = "SELECT nspname FROM pg_catalog.pg_namespace WHERE nspname NOT LIKE 'pg_temp_%' AND nspname NOT LIKE 'pg_toast_temp_%' ORDER BY nspname" - } else if s.mode.mysqlCompat { - query = kingbaseMySQLCompatListSchemasSQL +func kingbaseListSchemasSQL(mode kingbaseMode, showSystemSchemas bool) string { + if mode.mysqlCompat { + if showSystemSchemas { + return "SELECT schema_name FROM information_schema.schemata ORDER BY schema_name" + } + return kingbaseMySQLCompatListSchemasSQL } + if mode.postgresCatalog { + if showSystemSchemas { + return "SELECT nspname FROM pg_catalog.pg_namespace ORDER BY nspname" + } + return "SELECT nspname FROM pg_catalog.pg_namespace WHERE nspname NOT LIKE 'pg_temp_%' AND nspname NOT LIKE 'pg_toast_temp_%' ORDER BY nspname" + } + if showSystemSchemas { + return "SELECT nspname FROM sys_catalog.sys_namespace ORDER BY nspname" + } + return "SELECT nspname FROM sys_catalog.sys_namespace WHERE nspname NOT LIKE 'sys_temp_%' AND nspname NOT LIKE 'sys_toast_temp_%' ORDER BY nspname" +} + +func (s *server) listSchemas(visible []string, showSystemSchemas bool) ([]string, error) { + query := kingbaseListSchemasSQL(s.mode, showSystemSchemas) rows, err := s.metadataQuery(query) if err != nil { return nil, err @@ -383,7 +397,7 @@ func (s *server) completionAssistantSearch(request completionAssistantRequest) ( } else { schemas := []string{request.Schema} if request.GlobalSearch { - visible, err := s.listSchemas(nil) + visible, err := s.listSchemas(nil, false) if err != nil { return completionAssistantResponse{}, err } diff --git a/agents/drivers/kingbase-go/main.go b/agents/drivers/kingbase-go/main.go index 79cf709af..530b772ac 100644 --- a/agents/drivers/kingbase-go/main.go +++ b/agents/drivers/kingbase-go/main.go @@ -367,7 +367,7 @@ func (s *server) dispatch(method string, params map[string]json.RawMessage) (any result, err := s.listDatabases() return result, false, err case "list_schemas": - result, err := s.listSchemas(stringSliceParam(params, "visible_schemas")) + result, err := s.listSchemas(stringSliceParam(params, "visible_schemas"), boolParam(params, "show_system_schemas")) return result, false, err case "list_tables": result, err := s.listTables(stringParam(params, "schema"), metadataListConstraintsFromParams(params)) @@ -1138,6 +1138,14 @@ func intParam(params map[string]json.RawMessage, key string) int { return value } +func boolParam(params map[string]json.RawMessage, key string) bool { + var value bool + if raw, ok := params[key]; ok { + _ = json.Unmarshal(raw, &value) + } + return value +} + func stringSliceParam(params map[string]json.RawMessage, key string) []string { var values []string if json.Unmarshal(params[key], &values) == nil { diff --git a/agents/drivers/kingbase-go/main_test.go b/agents/drivers/kingbase-go/main_test.go index 3f75cebc6..9ae68430c 100644 --- a/agents/drivers/kingbase-go/main_test.go +++ b/agents/drivers/kingbase-go/main_test.go @@ -706,6 +706,24 @@ func TestMySQLCompatSchemaQueryKeepsUserSchemasWithSystemLikeNames(t *testing.T) } } +func TestListSchemasQueryIncludesSystemSchemasWhenEnabled(t *testing.T) { + for _, mode := range []kingbaseMode{{}, {postgresCatalog: true}, {mysqlCompat: true}} { + query := kingbaseListSchemasSQL(mode, true) + if strings.Contains(query, "NOT LIKE") || strings.Contains(query, "<>") { + t.Fatalf("show-system query must not filter schemas: %s", query) + } + } +} + +func TestListSchemasQueryKeepsDefaultTemporarySchemaFilters(t *testing.T) { + for _, mode := range []kingbaseMode{{}, {postgresCatalog: true}} { + query := kingbaseListSchemasSQL(mode, false) + if !strings.Contains(query, "temp_%") { + t.Fatalf("default query must keep temporary schema filters: %s", query) + } + } +} + func TestMetadataNormalizationHelpers(t *testing.T) { if normalizeTableType("BASE TABLE") != "TABLE" { t.Fatal("BASE TABLE was not normalized") diff --git a/apps/desktop/src/components/connection/ConnectionDialog.vue b/apps/desktop/src/components/connection/ConnectionDialog.vue index 17b72e3da..1e1f9af97 100644 --- a/apps/desktop/src/components/connection/ConnectionDialog.vue +++ b/apps/desktop/src/components/connection/ConnectionDialog.vue @@ -255,6 +255,7 @@ const defaultForm = (): ConnectionForm => ({ external_config: undefined, init_script: undefined, read_only: false, + show_system_schemas: false, is_production: false, production_databases: [], visible_databases: undefined, @@ -1994,6 +1995,7 @@ watch( attached_databases: config.attached_databases || [], init_script: config.init_script, read_only: config.read_only || false, + show_system_schemas: config.show_system_schemas || false, is_production: config.is_production || false, production_databases: config.production_databases || [], visible_databases: config.visible_databases, @@ -3391,6 +3393,7 @@ function connectionConfigForSubmit(id: string, generatedName = ""): ConnectionCo } else { config.visible_databases = Array.isArray(config.visible_databases) && config.visible_databases.length > 0 ? config.visible_databases : undefined; } + if (!config.show_system_schemas) config.show_system_schemas = undefined; if (config.visible_schemas && Object.keys(config.visible_schemas).length === 0) config.visible_schemas = undefined; if (config.agent_java_options && config.agent_java_options.length === 0) config.agent_java_options = undefined; return config as ConnectionConfig; @@ -6557,6 +6560,13 @@ function openExternalUrl(url: string) { {{ t("connection.readOnlyHint") }} +
+ + +