fix(postgres): keep expression index DDL text and key order in sync
This commit is contained in:
4 files changed
+213
-15
No files matched your search
@@ -542,10 +542,13 @@ public abstract class PostgresLikeAgent extends AbstractJdbcAgent {
|
||||
// dropped; their text comes from pg_get_indexdef instead of a.attname, and
|
||||
// is_expression records which case applied so Rust never has to guess from
|
||||
// characters in the text (#6312 review).
|
||||
// `a.attname::text` keeps the cast: a bare COALESCE(name, text) resolves to
|
||||
// `name`, which truncates an expression key part to 63 bytes (NAMEDATALEN - 1)
|
||||
// and makes the rebuilt CREATE INDEX invalid (#9988).
|
||||
Map<String, IndexBuilder> byName = new LinkedHashMap<>();
|
||||
String sql = "SELECT i.relname AS index_name, am.amname AS index_type, " +
|
||||
"(ix.indisunique AND ix.indisvalid) AS is_unique, ix.indisprimary AS is_primary, " +
|
||||
"COALESCE(a.attname, " + profile.catalogPrefixedFunction("get_indexdef") + "(ix.indexrelid, k.n, true)) AS column_text, " +
|
||||
"COALESCE(a.attname::text, " + profile.catalogPrefixedFunction("get_indexdef") + "(ix.indexrelid, k.n, true)) AS column_text, " +
|
||||
"(a.attname IS NULL) AS is_expression, " +
|
||||
"array_length(ix.indoption, 1) AS nkeyatts, k.n AS key_position, " +
|
||||
"ix.indoption[(k.n - 1)::int] AS key_option " +
|
||||
|
||||
@@ -201,6 +201,9 @@ class PostgresLikeAgentTest {
|
||||
String sql = String.join("\n", MetadataSqlFake.statements);
|
||||
assertTrue(sql.contains("LEFT JOIN pg_catalog.pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum AND k.attnum > 0"), sql);
|
||||
assertTrue(sql.contains("pg_catalog.pg_get_indexdef(ix.indexrelid, k.n, true)"), sql);
|
||||
// #9988: a bare COALESCE(name, text) resolves to `name`, so PostgreSQL truncated a
|
||||
// long expression key part to 63 bytes and the rebuilt CREATE INDEX was invalid.
|
||||
assertTrue(sql.contains("COALESCE(a.attname::text, pg_catalog.pg_get_indexdef(ix.indexrelid, k.n, true)) AS column_text"), sql);
|
||||
assertTrue(sql.contains("ix.indisunique AND ix.indisvalid"), sql);
|
||||
assertTrue(sql.contains("ix.indoption[(k.n - 1)::int]"), sql);
|
||||
assertTrue(sql.contains("array_length(ix.indoption, 1) AS nkeyatts"), sql);
|
||||
|
||||
Reference in new issue
Block a user