diff --git a/agents/drivers/kingbase-go/kingbase_metadata.go b/agents/drivers/kingbase-go/kingbase_metadata.go index 6a2c6f0805..8e080d1086 100644 --- a/agents/drivers/kingbase-go/kingbase_metadata.go +++ b/agents/drivers/kingbase-go/kingbase_metadata.go @@ -152,6 +152,15 @@ func mysqlSQLModeExists(db *sql.DB) bool { return db.QueryRow("SELECT 1 FROM sys_catalog.sys_settings WHERE LOWER(name) = 'sql_mode'").Scan(&value) == nil } +func (s *server) identifierQuote() string { + // Kingbase MySQL compatibility mode follows MySQL identifier quoting; + // other modes retain the PostgreSQL-compatible double quote. + if s.mode.mysqlCompat { + return "`" + } + return `"` +} + func (s *server) connectionInfo() (map[string]any, error) { db, err := s.requireDB() if err != nil { @@ -164,7 +173,7 @@ func (s *server) connectionInfo() (map[string]any, error) { } return map[string]any{ "database": database, "username": username, "version": version, "schema": schema, - "mysql_compat_mode": s.mode.mysqlCompat, + "mysql_compat_mode": s.mode.mysqlCompat, "identifierQuote": s.identifierQuote(), }, nil } diff --git a/agents/drivers/kingbase-go/main_test.go b/agents/drivers/kingbase-go/main_test.go index 09d7d2c294..dcb30a9fc3 100644 --- a/agents/drivers/kingbase-go/main_test.go +++ b/agents/drivers/kingbase-go/main_test.go @@ -163,6 +163,11 @@ func (connection *modeDetectionConn) QueryContext(_ context.Context, query strin connection.state.mu.Unlock() switch { + case strings.Contains(query, "SELECT current_database()"): + return &valueRows{ + columns: []string{"current_database", "current_user", "version", "current_schema"}, + rows: [][]driver.Value{{"test", "system", "KingbaseES", "public"}}, + }, nil case strings.Contains(query, "LOWER(name) = 'database_mode'"): if connection.state.databaseErr != nil { return nil, connection.state.databaseErr @@ -470,6 +475,32 @@ func TestDetectMySQLCompatModePrefersDatabaseModeOverSQLModePresence(t *testing. } } +func TestConnectionInfoReportsCompatibilityIdentifierQuote(t *testing.T) { + for _, testCase := range []struct { + name string + mysqlCompat bool + expected string + }{ + {name: "postgres compatible", expected: `"`}, + {name: "mysql compatible", mysqlCompat: true, expected: "`"}, + } { + t.Run(testCase.name, func(t *testing.T) { + db := openModeDetectionDB(t, &modeDetectionDriverState{}) + server := newServer() + server.db = db + server.mode.mysqlCompat = testCase.mysqlCompat + + info, err := server.connectionInfo() + if err != nil { + t.Fatal(err) + } + if info["identifierQuote"] != testCase.expected { + t.Fatalf("unexpected identifier quote: %#v", info["identifierQuote"]) + } + }) + } +} + func TestDetectMySQLCompatModeFallsBackToSQLModeWhenDatabaseModeMissing(t *testing.T) { state := &modeDetectionDriverState{sqlModeExists: true} db := openModeDetectionDB(t, state) diff --git a/crates/dbx-core/src/sql_dialect/tests.rs b/crates/dbx-core/src/sql_dialect/tests.rs index bac84686b9..54f10fa09b 100644 --- a/crates/dbx-core/src/sql_dialect/tests.rs +++ b/crates/dbx-core/src/sql_dialect/tests.rs @@ -316,7 +316,7 @@ fn builds_table_data_where_and_schema_queries() { build_table_data_select_sql(TableDataSelectSqlOptions { database_type: Some(DatabaseType::Kingbase), identifier_quote: Some("`".to_string()), - schema: Some("cqbq_ls".to_string()), + schema: Some("nacos-v3".to_string()), table_name: "actionlogs".to_string(), table_type: None, primary_keys: Vec::new(), @@ -329,7 +329,7 @@ fn builds_table_data_where_and_schema_queries() { include_row_id: false, ..Default::default() }), - "SELECT * FROM `cqbq_ls`.`actionlogs` LIMIT 100;" + "SELECT * FROM `nacos-v3`.`actionlogs` LIMIT 100;" ); assert_eq!( build_table_data_select_sql(TableDataSelectSqlOptions {