fix(kingbase): load indexes in SQL Server mode

This commit is contained in:
zipg 2026-07-20 23:29:43 +08:00 committed by GitHub
parent 79f8c7284a
commit 3650b6026e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 25 additions and 9 deletions

View File

@ -488,13 +488,7 @@ func (s *server) listIndexes(schema, table string) ([]indexInfo, error) {
if s.mode.postgresCatalog {
catalog, prefix = "pg_catalog", "pg"
}
query := fmt.Sprintf(`SELECT i.relname, am.amname, ix.indisunique, ix.indisprimary, a.attname, pos.n
FROM %s.%s_index ix JOIN %s.%s_class t ON t.oid = ix.indrelid
JOIN %s.%s_class i ON i.oid = ix.indexrelid JOIN %s.%s_namespace n ON n.oid = t.relnamespace
JOIN %s.%s_am am ON am.oid = i.relam
JOIN generate_series(1,64) pos(n) ON pos.n <= array_length(string_to_array(ix.indkey::text,' '),1)
JOIN %s.%s_attribute a ON a.attrelid = t.oid AND a.attnum = (string_to_array(ix.indkey::text,' '))[pos.n]::int2
WHERE n.nspname = %s AND t.relname = %s ORDER BY i.relname, pos.n`, catalog, prefix, catalog, prefix, catalog, prefix, catalog, prefix, catalog, prefix, catalog, prefix, quoteLiteral(effective), quoteLiteral(table))
query := kingbaseListIndexesQuery(catalog, prefix, effective, table)
rows, err := s.metadataQuery(query)
if err != nil {
return nil, err
@ -524,6 +518,16 @@ WHERE n.nspname = %s AND t.relname = %s ORDER BY i.relname, pos.n`, catalog, pre
return result, rows.Err()
}
func kingbaseListIndexesQuery(catalog, prefix, schema, table string) string {
return fmt.Sprintf(`SELECT i.relname, am.amname, ix.indisunique, ix.indisprimary, a.attname, pos.n
FROM %s.%s_index ix JOIN %s.%s_class t ON t.oid = ix.indrelid
JOIN %s.%s_class i ON i.oid = ix.indexrelid JOIN %s.%s_namespace n ON n.oid = t.relnamespace
JOIN %s.%s_am am ON am.oid = i.relam
JOIN unnest(ix.indkey) WITH ORDINALITY AS pos(attnum,n) ON true
JOIN %s.%s_attribute a ON a.attrelid = t.oid AND a.attnum = pos.attnum
WHERE n.nspname = %s AND t.relname = %s ORDER BY i.relname, pos.n`, catalog, prefix, catalog, prefix, catalog, prefix, catalog, prefix, catalog, prefix, catalog, prefix, quoteLiteral(schema), quoteLiteral(table))
}
func (s *server) listForeignKeys(schema, table string) ([]foreignKeyInfo, error) {
effective, err := s.effectiveSchema(schema)
if err != nil {

View File

@ -192,6 +192,16 @@ func TestBuildDSNConvertsDBXJDBCURL(t *testing.T) {
}
}
func TestKingbaseListIndexesQuerySupportsSQLServerMode(t *testing.T) {
query := kingbaseListIndexesQuery("sys_catalog", "sys", "public", "orders")
if !strings.Contains(query, "unnest(ix.indkey) WITH ORDINALITY") {
t.Fatalf("index query should preserve index column order without array subscripts: %s", query)
}
if strings.Contains(query, "[pos.n]") {
t.Fatalf("index query should not use dynamic array subscripts in SQL Server mode: %s", query)
}
}
func TestMetadataNormalizationHelpers(t *testing.T) {
if normalizeTableType("BASE TABLE") != "TABLE" {
t.Fatal("BASE TABLE was not normalized")

View File

@ -668,8 +668,8 @@ public final class KingbaseAgent extends PostgresLikeAgent {
"JOIN SYS_CATALOG.SYS_CLASS i ON i.oid = ix.indexrelid " +
"JOIN SYS_CATALOG.SYS_NAMESPACE n ON n.oid = t.relnamespace " +
"JOIN SYS_CATALOG.SYS_AM am ON am.oid = i.relam " +
"JOIN generate_series(1, 64) AS pos(n) ON pos.n <= array_length(string_to_array(ix.indkey::text, ' '), 1) " +
"JOIN SYS_CATALOG.SYS_ATTRIBUTE a ON a.attrelid = t.oid AND a.attnum = (string_to_array(ix.indkey::text, ' '))[pos.n]::int2 " +
"JOIN unnest(ix.indkey) WITH ORDINALITY AS pos(attnum, n) ON true " +
"JOIN SYS_CATALOG.SYS_ATTRIBUTE a ON a.attrelid = t.oid AND a.attnum = pos.attnum " +
"WHERE n.nspname = " + sqlString(effectiveSchema(schema)) +
" AND t.relname = " + sqlString(table) + " " +
"ORDER BY i.relname, pos.n";

View File

@ -786,6 +786,8 @@ class KingbaseAgentTest extends JdbcFakeExecutionBehaviorTest {
Assertions.assertFalse(indexes.get(1).getIs_primary());
Assertions.assertEquals(Arrays.asList("name", "created"), indexes.get(2).getColumns());
Assertions.assertTrue(sql.get(0).contains("FROM SYS_CATALOG.SYS_INDEX"), sql.get(0));
Assertions.assertTrue(sql.get(0).contains("unnest(ix.indkey) WITH ORDINALITY"), sql.get(0));
Assertions.assertFalse(sql.get(0).contains("[pos.n]"), sql.get(0));
Assertions.assertFalse(sql.get(0).contains("information_schema.table_constraints"), sql.get(0));
}