From b8afee10c7e7c7e6c1265627c54143c76a5e3aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20R=C4=85czka?= <04_barista_pads@icloud.com> Date: Sat, 13 Sep 2025 11:44:52 +0200 Subject: [PATCH 1/3] fix: add proper quoting for camelCase columns in CREATE INDEX Problem: CREATE INDEX statements were generating column names without quotes, causing PostgreSQL to lowercase them (assignedTo -> assignedto). Solution: Use util.QuoteIdentifier() for simple column names, but avoid quoting functional expressions like lower(email) or upper(firstName). Changes: - internal/diff/index.go: Fixed regular CREATE INDEX statements - internal/plan/rewrite.go: Fixed CREATE INDEX CONCURRENTLY statements - Added comprehensive tests for camelCase, functional indexes, and reserved words This ensures: - camelCase columns are quoted: "assignedTo" - lowercase columns remain unquoted: email - reserved words are quoted: "order", "user" - functional expressions remain unquoted: lower(email) --- internal/diff/index.go | 6 +- internal/diff/index_test.go | 174 ++++++++++++++++++ internal/plan/rewrite.go | 9 +- .../diff/online/add_camelcase_index/diff.sql | 3 + .../diff/online/add_camelcase_index/new.sql | 9 + .../diff/online/add_camelcase_index/old.sql | 6 + .../diff/online/add_camelcase_index/plan.json | 36 ++++ .../diff/online/add_camelcase_index/plan.sql | 36 ++++ .../diff/online/add_camelcase_index/plan.txt | 48 +++++ 9 files changed, 325 insertions(+), 2 deletions(-) create mode 100644 internal/diff/index_test.go create mode 100644 testdata/diff/online/add_camelcase_index/diff.sql create mode 100644 testdata/diff/online/add_camelcase_index/new.sql create mode 100644 testdata/diff/online/add_camelcase_index/old.sql create mode 100644 testdata/diff/online/add_camelcase_index/plan.json create mode 100644 testdata/diff/online/add_camelcase_index/plan.sql create mode 100644 testdata/diff/online/add_camelcase_index/plan.txt diff --git a/internal/diff/index.go b/internal/diff/index.go index b01e5e36..d3932c58 100644 --- a/internal/diff/index.go +++ b/internal/diff/index.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/pgschema/pgschema/internal/ir" + "github.com/pgschema/pgschema/internal/util" ) // generateCreateIndexesSQL generates CREATE INDEX statements @@ -100,8 +101,11 @@ func generateIndexSQLWithName(index *ir.Index, indexName string, targetSchema st if strings.Contains(col.Name, "->>") || strings.Contains(col.Name, "->") { // Use double parentheses for JSON expressions for clean format builder.WriteString(fmt.Sprintf("((%s))", col.Name)) - } else { + } else if strings.Contains(col.Name, "(") || strings.Contains(col.Name, ")") { + // Functional expressions like lower(column) should not be quoted builder.WriteString(col.Name) + } else { + builder.WriteString(util.QuoteIdentifier(col.Name)) } // Add direction if specified diff --git a/internal/diff/index_test.go b/internal/diff/index_test.go new file mode 100644 index 00000000..e1bca3b0 --- /dev/null +++ b/internal/diff/index_test.go @@ -0,0 +1,174 @@ +package diff + +import ( + "strings" + "testing" + + "github.com/pgschema/pgschema/internal/ir" +) + +func TestGenerateIndexSQL_CamelCaseColumns(t *testing.T) { + tests := []struct { + name string + index *ir.Index + expected string + }{ + { + name: "single camelCase column", + index: &ir.Index{ + Name: "idx_invite_assignedTo", + Schema: "public", + Table: "invite", + Columns: []*ir.IndexColumn{ + {Name: "assignedTo"}, + }, + }, + expected: `CREATE INDEX IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo");`, + }, + { + name: "multiple camelCase columns", + index: &ir.Index{ + Name: "idx_invite_composite", + Schema: "public", + Table: "invite", + Columns: []*ir.IndexColumn{ + {Name: "createdAt"}, + {Name: "invitedBy"}, + }, + }, + expected: `CREATE INDEX IF NOT EXISTS idx_invite_composite ON invite ("createdAt", "invitedBy");`, + }, + { + name: "mixed case and lowercase columns", + index: &ir.Index{ + Name: "idx_mixed", + Schema: "public", + Table: "users", + Columns: []*ir.IndexColumn{ + {Name: "firstName"}, + {Name: "email"}, + {Name: "lastName"}, + }, + }, + expected: `CREATE INDEX IF NOT EXISTS idx_mixed ON users ("firstName", email, "lastName");`, + }, + { + name: "unique index with camelCase", + index: &ir.Index{ + Name: "uk_user_email", + Schema: "public", + Table: "user", + Type: ir.IndexTypeUnique, + Columns: []*ir.IndexColumn{ + {Name: "emailAddress"}, + }, + }, + expected: `CREATE UNIQUE INDEX IF NOT EXISTS uk_user_email ON "user" ("emailAddress");`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := generateIndexSQL(tt.index, "public", false) + if result != tt.expected { + t.Errorf("generateIndexSQL() = %q; want %q", result, tt.expected) + } + }) + } +} + +func TestGenerateIndexSQL_Concurrent_CamelCase(t *testing.T) { + index := &ir.Index{ + Name: "idx_invite_assignedTo", + Schema: "public", + Table: "invite", + Columns: []*ir.IndexColumn{ + {Name: "assignedTo"}, + }, + } + + result := generateIndexSQL(index, "public", true) + expected := `CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo");` + + if result != expected { + t.Errorf("generateIndexSQL(concurrent=true) = %q; want %q", result, expected) + } +} + +func TestGenerateIndexSQL_ReservedWords(t *testing.T) { + index := &ir.Index{ + Name: "idx_user_order", + Schema: "public", + Table: "user", // reserved word + Columns: []*ir.IndexColumn{ + {Name: "order"}, // reserved word + {Name: "userId"}, + }, + } + + result := generateIndexSQL(index, "public", false) + + // Both "user" and "order" should be quoted as reserved words + if !strings.Contains(result, `"user"`) { + t.Errorf("Table name 'user' should be quoted") + } + if !strings.Contains(result, `"order"`) { + t.Errorf("Column name 'order' should be quoted") + } +} + +func TestGenerateIndexSQL_FunctionalIndex(t *testing.T) { + tests := []struct { + name string + index *ir.Index + expected string + }{ + { + name: "functional index with lower", + index: &ir.Index{ + Name: "idx_users_lower_email", + Schema: "public", + Table: "users", + Columns: []*ir.IndexColumn{ + {Name: "lower(email)"}, + }, + }, + expected: `CREATE INDEX IF NOT EXISTS idx_users_lower_email ON users (lower(email));`, + }, + { + name: "functional index with upper on camelCase column", + index: &ir.Index{ + Name: "idx_users_upper_firstname", + Schema: "public", + Table: "users", + Columns: []*ir.IndexColumn{ + {Name: "upper(firstName)"}, // firstName inside function should not be quoted + }, + }, + expected: `CREATE INDEX IF NOT EXISTS idx_users_upper_firstname ON users (upper(firstName));`, + }, + { + name: "mixed functional and regular columns", + index: &ir.Index{ + Name: "idx_mixed_func", + Schema: "public", + Table: "users", + Columns: []*ir.IndexColumn{ + {Name: "lower(email)"}, + {Name: "lastName"}, // regular camelCase should be quoted + {Name: "age"}, // regular lowercase should not be quoted + }, + }, + expected: `CREATE INDEX IF NOT EXISTS idx_mixed_func ON users (lower(email), "lastName", age);`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := generateIndexSQL(tt.index, "public", false) + if result != tt.expected { + t.Errorf("generateIndexSQL() = %q; want %q", result, tt.expected) + } + }) + } +} \ No newline at end of file diff --git a/internal/plan/rewrite.go b/internal/plan/rewrite.go index 37883c7e..47224607 100644 --- a/internal/plan/rewrite.go +++ b/internal/plan/rewrite.go @@ -6,6 +6,7 @@ import ( "github.com/pgschema/pgschema/internal/diff" "github.com/pgschema/pgschema/internal/ir" + "github.com/pgschema/pgschema/internal/util" ) // RewriteStep represents a single step in a rewrite operation @@ -307,7 +308,13 @@ func generateIndexSQL(index *ir.Index, isConcurrent bool) string { var columnParts []string for _, col := range index.Columns { - part := col.Name + var part string + // Don't quote functional expressions + if strings.Contains(col.Name, "(") || strings.Contains(col.Name, ")") { + part = col.Name + } else { + part = util.QuoteIdentifier(col.Name) + } if col.Direction != "" && col.Direction != "ASC" { part += " " + col.Direction } diff --git a/testdata/diff/online/add_camelcase_index/diff.sql b/testdata/diff/online/add_camelcase_index/diff.sql new file mode 100644 index 00000000..ca8ad682 --- /dev/null +++ b/testdata/diff/online/add_camelcase_index/diff.sql @@ -0,0 +1,3 @@ +CREATE INDEX IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo"); + +CREATE INDEX IF NOT EXISTS idx_invite_created_invited ON invite ("createdAt", "invitedBy"); \ No newline at end of file diff --git a/testdata/diff/online/add_camelcase_index/new.sql b/testdata/diff/online/add_camelcase_index/new.sql new file mode 100644 index 00000000..e69f9d48 --- /dev/null +++ b/testdata/diff/online/add_camelcase_index/new.sql @@ -0,0 +1,9 @@ +CREATE TABLE public.invite ( + id text NOT NULL, + "invitedBy" text, + "assignedTo" text, + "createdAt" timestamp with time zone +); + +CREATE INDEX "idx_invite_assignedTo" ON public.invite ("assignedTo"); +CREATE INDEX idx_invite_created_invited ON public.invite ("createdAt", "invitedBy"); \ No newline at end of file diff --git a/testdata/diff/online/add_camelcase_index/old.sql b/testdata/diff/online/add_camelcase_index/old.sql new file mode 100644 index 00000000..253ff66d --- /dev/null +++ b/testdata/diff/online/add_camelcase_index/old.sql @@ -0,0 +1,6 @@ +CREATE TABLE public.invite ( + id text NOT NULL, + "invitedBy" text, + "assignedTo" text, + "createdAt" timestamp with time zone +); \ No newline at end of file diff --git a/testdata/diff/online/add_camelcase_index/plan.json b/testdata/diff/online/add_camelcase_index/plan.json new file mode 100644 index 00000000..98c8fa45 --- /dev/null +++ b/testdata/diff/online/add_camelcase_index/plan.json @@ -0,0 +1,36 @@ +{ + "can_run_in_transaction": false, + "has_unsafe_operations": false, + "rewrite_steps": [ + { + "sql": "CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_assignedTo ON invite (\"assignedTo\");", + "can_run_in_transaction": false + }, + { + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_stat_progress_create_index p\nLEFT JOIN pg_class c ON p.relid = c.oid\nLEFT JOIN pg_indexes idx ON idx.tablename = c.relname\nLEFT JOIN pg_class ic ON ic.relname = idx.indexname\nLEFT JOIN pg_index i ON i.indexrelid = ic.oid\nWHERE idx.indexname = 'idx_invite_assignedTo' OR p.index_relid = ic.oid;", + "can_run_in_transaction": true, + "directive": { + "type": "wait", + "properties": { + "query": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_stat_progress_create_index p\nLEFT JOIN pg_class c ON p.relid = c.oid\nLEFT JOIN pg_indexes idx ON idx.tablename = c.relname\nLEFT JOIN pg_class ic ON ic.relname = idx.indexname\nLEFT JOIN pg_index i ON i.indexrelid = ic.oid\nWHERE idx.indexname = 'idx_invite_assignedTo' OR p.index_relid = ic.oid;", + "message": "Creating index idx_invite_assignedTo" + } + } + }, + { + "sql": "CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_created_invited ON invite (\"createdAt\", \"invitedBy\");", + "can_run_in_transaction": false + }, + { + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_stat_progress_create_index p\nLEFT JOIN pg_class c ON p.relid = c.oid\nLEFT JOIN pg_indexes idx ON idx.tablename = c.relname\nLEFT JOIN pg_class ic ON ic.relname = idx.indexname\nLEFT JOIN pg_index i ON i.indexrelid = ic.oid\nWHERE idx.indexname = 'idx_invite_created_invited' OR p.index_relid = ic.oid;", + "can_run_in_transaction": true, + "directive": { + "type": "wait", + "properties": { + "query": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_stat_progress_create_index p\nLEFT JOIN pg_class c ON p.relid = c.oid\nLEFT JOIN pg_indexes idx ON idx.tablename = c.relname\nLEFT JOIN pg_class ic ON ic.relname = idx.indexname\nLEFT JOIN pg_index i ON i.indexrelid = ic.oid\nWHERE idx.indexname = 'idx_invite_created_invited' OR p.index_relid = ic.oid;", + "message": "Creating index idx_invite_created_invited" + } + } + } + ] +} diff --git a/testdata/diff/online/add_camelcase_index/plan.sql b/testdata/diff/online/add_camelcase_index/plan.sql new file mode 100644 index 00000000..e5b22068 --- /dev/null +++ b/testdata/diff/online/add_camelcase_index/plan.sql @@ -0,0 +1,36 @@ +-- +-- pgschema plan +-- +-- This migration cannot run inside a transaction block. +-- Manual intervention may be required if it fails partway through. +-- + +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo"); + +SELECT + COALESCE(i.indisvalid, false) as done, + CASE + WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total + ELSE 0 + END as progress +FROM pg_stat_progress_create_index p +LEFT JOIN pg_class c ON p.relid = c.oid +LEFT JOIN pg_indexes idx ON idx.tablename = c.relname +LEFT JOIN pg_class ic ON ic.relname = idx.indexname +LEFT JOIN pg_index i ON i.indexrelid = ic.oid +WHERE idx.indexname = 'idx_invite_assignedTo' OR p.index_relid = ic.oid; + +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_created_invited ON invite ("createdAt", "invitedBy"); + +SELECT + COALESCE(i.indisvalid, false) as done, + CASE + WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total + ELSE 0 + END as progress +FROM pg_stat_progress_create_index p +LEFT JOIN pg_class c ON p.relid = c.oid +LEFT JOIN pg_indexes idx ON idx.tablename = c.relname +LEFT JOIN pg_class ic ON ic.relname = idx.indexname +LEFT JOIN pg_index i ON i.indexrelid = ic.oid +WHERE idx.indexname = 'idx_invite_created_invited' OR p.index_relid = ic.oid; \ No newline at end of file diff --git a/testdata/diff/online/add_camelcase_index/plan.txt b/testdata/diff/online/add_camelcase_index/plan.txt new file mode 100644 index 00000000..5de31ee6 --- /dev/null +++ b/testdata/diff/online/add_camelcase_index/plan.txt @@ -0,0 +1,48 @@ +Plan: 2 to add. + +Summary by type: + indexes: 2 to add + +Indexes: + + idx_invite_assignedTo + + idx_invite_created_invited + +DDL to be executed: +-------------------------------------------------- + +-- +-- pgschema plan +-- +-- This migration cannot run inside a transaction block. +-- Manual intervention may be required if it fails partway through. +-- + +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo"); + +SELECT + COALESCE(i.indisvalid, false) as done, + CASE + WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total + ELSE 0 + END as progress +FROM pg_stat_progress_create_index p +LEFT JOIN pg_class c ON p.relid = c.oid +LEFT JOIN pg_indexes idx ON idx.tablename = c.relname +LEFT JOIN pg_class ic ON ic.relname = idx.indexname +LEFT JOIN pg_index i ON i.indexrelid = ic.oid +WHERE idx.indexname = 'idx_invite_assignedTo' OR p.index_relid = ic.oid; + +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_created_invited ON invite ("createdAt", "invitedBy"); + +SELECT + COALESCE(i.indisvalid, false) as done, + CASE + WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total + ELSE 0 + END as progress +FROM pg_stat_progress_create_index p +LEFT JOIN pg_class c ON p.relid = c.oid +LEFT JOIN pg_indexes idx ON idx.tablename = c.relname +LEFT JOIN pg_class ic ON ic.relname = idx.indexname +LEFT JOIN pg_index i ON i.indexrelid = ic.oid +WHERE idx.indexname = 'idx_invite_created_invited' OR p.index_relid = ic.oid; \ No newline at end of file From 99583a660e9ca2916b378ce8ca5a037dc339bf31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20R=C4=85czka?= <04_barista_pads@icloud.com> Date: Sat, 13 Sep 2025 11:58:21 +0200 Subject: [PATCH 2/3] fix: add proper quoting for camelCase columns and index names in CREATE INDEX Problem: CREATE INDEX statements were missing quotes for: 1. CamelCase column names (assignedTo -> assignedto) 2. CamelCase index names (idx_invite_assignedTo -> idx_invite_assignedto) Solution: Use util.QuoteIdentifier() for: - Index names with camelCase - Simple column names (but not functional expressions) Changes: - internal/diff/index.go: Quote index names and column names - internal/plan/rewrite.go: Quote index names for CONCURRENTLY - Added comprehensive tests for all scenarios - Fixed test data to expect quoted index names This ensures proper quoting while preserving functional indexes like lower(email) --- internal/diff/index.go | 2 +- internal/diff/index_test.go | 4 +- internal/plan/rewrite.go | 4 +- .../diff/online/add_camelcase_index/diff.sql | 2 +- .../diff/online/add_camelcase_index/plan.json | 10 ++-- .../diff/online/add_camelcase_index/plan.sql | 31 +++++-------- .../diff/online/add_camelcase_index/plan.txt | 46 +++++++++---------- 7 files changed, 43 insertions(+), 56 deletions(-) diff --git a/internal/diff/index.go b/internal/diff/index.go index d3932c58..8a0e69c8 100644 --- a/internal/diff/index.go +++ b/internal/diff/index.go @@ -77,7 +77,7 @@ func generateIndexSQLWithName(index *ir.Index, indexName string, targetSchema st builder.WriteString("IF NOT EXISTS ") // Index name - builder.WriteString(indexName) + builder.WriteString(util.QuoteIdentifier(indexName)) builder.WriteString(" ON ") // Table name with proper schema qualification diff --git a/internal/diff/index_test.go b/internal/diff/index_test.go index e1bca3b0..f7292cea 100644 --- a/internal/diff/index_test.go +++ b/internal/diff/index_test.go @@ -23,7 +23,7 @@ func TestGenerateIndexSQL_CamelCaseColumns(t *testing.T) { {Name: "assignedTo"}, }, }, - expected: `CREATE INDEX IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo");`, + expected: `CREATE INDEX IF NOT EXISTS "idx_invite_assignedTo" ON invite ("assignedTo");`, }, { name: "multiple camelCase columns", @@ -88,7 +88,7 @@ func TestGenerateIndexSQL_Concurrent_CamelCase(t *testing.T) { } result := generateIndexSQL(index, "public", true) - expected := `CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo");` + expected := `CREATE INDEX CONCURRENTLY IF NOT EXISTS "idx_invite_assignedTo" ON invite ("assignedTo");` if result != expected { t.Errorf("generateIndexSQL(concurrent=true) = %q; want %q", result, expected) diff --git a/internal/plan/rewrite.go b/internal/plan/rewrite.go index 47224607..d00ec17c 100644 --- a/internal/plan/rewrite.go +++ b/internal/plan/rewrite.go @@ -293,7 +293,7 @@ func generateIndexSQL(index *ir.Index, isConcurrent bool) string { sql.WriteString(" CONCURRENTLY") } sql.WriteString(" IF NOT EXISTS ") - sql.WriteString(index.Name) + sql.WriteString(util.QuoteIdentifier(index.Name)) sql.WriteString(" ON ") tableName := getTableNameWithSchema(index.Schema, index.Table) @@ -347,7 +347,7 @@ func generateIndexWaitQueryWithName(indexName string) string { FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = '%s';`, indexName) +WHERE lower(c.relname) = lower('%s');`, indexName) } // Helper functions diff --git a/testdata/diff/online/add_camelcase_index/diff.sql b/testdata/diff/online/add_camelcase_index/diff.sql index ca8ad682..98d3b562 100644 --- a/testdata/diff/online/add_camelcase_index/diff.sql +++ b/testdata/diff/online/add_camelcase_index/diff.sql @@ -1,3 +1,3 @@ -CREATE INDEX IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo"); +CREATE INDEX IF NOT EXISTS "idx_invite_assignedTo" ON invite ("assignedTo"); CREATE INDEX IF NOT EXISTS idx_invite_created_invited ON invite ("createdAt", "invitedBy"); \ No newline at end of file diff --git a/testdata/diff/online/add_camelcase_index/plan.json b/testdata/diff/online/add_camelcase_index/plan.json index 98c8fa45..e6db313e 100644 --- a/testdata/diff/online/add_camelcase_index/plan.json +++ b/testdata/diff/online/add_camelcase_index/plan.json @@ -3,16 +3,16 @@ "has_unsafe_operations": false, "rewrite_steps": [ { - "sql": "CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_assignedTo ON invite (\"assignedTo\");", + "sql": "CREATE INDEX CONCURRENTLY IF NOT EXISTS \"idx_invite_assignedTo\" ON invite (\"assignedTo\");", "can_run_in_transaction": false }, { - "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_stat_progress_create_index p\nLEFT JOIN pg_class c ON p.relid = c.oid\nLEFT JOIN pg_indexes idx ON idx.tablename = c.relname\nLEFT JOIN pg_class ic ON ic.relname = idx.indexname\nLEFT JOIN pg_index i ON i.indexrelid = ic.oid\nWHERE idx.indexname = 'idx_invite_assignedTo' OR p.index_relid = ic.oid;", + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_invite_assignedTo');", "can_run_in_transaction": true, "directive": { "type": "wait", "properties": { - "query": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_stat_progress_create_index p\nLEFT JOIN pg_class c ON p.relid = c.oid\nLEFT JOIN pg_indexes idx ON idx.tablename = c.relname\nLEFT JOIN pg_class ic ON ic.relname = idx.indexname\nLEFT JOIN pg_index i ON i.indexrelid = ic.oid\nWHERE idx.indexname = 'idx_invite_assignedTo' OR p.index_relid = ic.oid;", + "query": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_invite_assignedTo');", "message": "Creating index idx_invite_assignedTo" } } @@ -22,12 +22,12 @@ "can_run_in_transaction": false }, { - "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_stat_progress_create_index p\nLEFT JOIN pg_class c ON p.relid = c.oid\nLEFT JOIN pg_indexes idx ON idx.tablename = c.relname\nLEFT JOIN pg_class ic ON ic.relname = idx.indexname\nLEFT JOIN pg_index i ON i.indexrelid = ic.oid\nWHERE idx.indexname = 'idx_invite_created_invited' OR p.index_relid = ic.oid;", + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_invite_created_invited');", "can_run_in_transaction": true, "directive": { "type": "wait", "properties": { - "query": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_stat_progress_create_index p\nLEFT JOIN pg_class c ON p.relid = c.oid\nLEFT JOIN pg_indexes idx ON idx.tablename = c.relname\nLEFT JOIN pg_class ic ON ic.relname = idx.indexname\nLEFT JOIN pg_index i ON i.indexrelid = ic.oid\nWHERE idx.indexname = 'idx_invite_created_invited' OR p.index_relid = ic.oid;", + "query": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_invite_created_invited');", "message": "Creating index idx_invite_created_invited" } } diff --git a/testdata/diff/online/add_camelcase_index/plan.sql b/testdata/diff/online/add_camelcase_index/plan.sql index e5b22068..386e3a45 100644 --- a/testdata/diff/online/add_camelcase_index/plan.sql +++ b/testdata/diff/online/add_camelcase_index/plan.sql @@ -1,36 +1,27 @@ --- --- pgschema plan --- --- This migration cannot run inside a transaction block. --- Manual intervention may be required if it fails partway through. --- - -CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo"); +CREATE INDEX CONCURRENTLY IF NOT EXISTS "idx_invite_assignedTo" ON invite ("assignedTo"); +-- pgschema:wait SELECT COALESCE(i.indisvalid, false) as done, CASE WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total ELSE 0 END as progress -FROM pg_stat_progress_create_index p -LEFT JOIN pg_class c ON p.relid = c.oid -LEFT JOIN pg_indexes idx ON idx.tablename = c.relname -LEFT JOIN pg_class ic ON ic.relname = idx.indexname -LEFT JOIN pg_index i ON i.indexrelid = ic.oid -WHERE idx.indexname = 'idx_invite_assignedTo' OR p.index_relid = ic.oid; +FROM pg_class c +LEFT JOIN pg_index i ON c.oid = i.indexrelid +LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid +WHERE lower(c.relname) = lower('idx_invite_assignedTo'); CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_created_invited ON invite ("createdAt", "invitedBy"); +-- pgschema:wait SELECT COALESCE(i.indisvalid, false) as done, CASE WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total ELSE 0 END as progress -FROM pg_stat_progress_create_index p -LEFT JOIN pg_class c ON p.relid = c.oid -LEFT JOIN pg_indexes idx ON idx.tablename = c.relname -LEFT JOIN pg_class ic ON ic.relname = idx.indexname -LEFT JOIN pg_index i ON i.indexrelid = ic.oid -WHERE idx.indexname = 'idx_invite_created_invited' OR p.index_relid = ic.oid; \ No newline at end of file +FROM pg_class c +LEFT JOIN pg_index i ON c.oid = i.indexrelid +LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid +WHERE lower(c.relname) = lower('idx_invite_created_invited'); diff --git a/testdata/diff/online/add_camelcase_index/plan.txt b/testdata/diff/online/add_camelcase_index/plan.txt index 5de31ee6..f0519f1a 100644 --- a/testdata/diff/online/add_camelcase_index/plan.txt +++ b/testdata/diff/online/add_camelcase_index/plan.txt @@ -1,48 +1,44 @@ -Plan: 2 to add. +Plan: 1 to modify. Summary by type: - indexes: 2 to add + tables: 1 to modify -Indexes: - + idx_invite_assignedTo - + idx_invite_created_invited +Tables: + ~ invite + + idx_invite_assignedTo (index) + + idx_invite_created_invited (index) DDL to be executed: -------------------------------------------------- --- --- pgschema plan --- --- This migration cannot run inside a transaction block. --- Manual intervention may be required if it fails partway through. --- - -CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_assignedTo ON invite ("assignedTo"); +-- Transaction Group #1 +CREATE INDEX CONCURRENTLY IF NOT EXISTS "idx_invite_assignedTo" ON invite ("assignedTo"); +-- Transaction Group #2 +-- pgschema:wait SELECT COALESCE(i.indisvalid, false) as done, CASE WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total ELSE 0 END as progress -FROM pg_stat_progress_create_index p -LEFT JOIN pg_class c ON p.relid = c.oid -LEFT JOIN pg_indexes idx ON idx.tablename = c.relname -LEFT JOIN pg_class ic ON ic.relname = idx.indexname -LEFT JOIN pg_index i ON i.indexrelid = ic.oid -WHERE idx.indexname = 'idx_invite_assignedTo' OR p.index_relid = ic.oid; +FROM pg_class c +LEFT JOIN pg_index i ON c.oid = i.indexrelid +LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid +WHERE lower(c.relname) = lower('idx_invite_assignedTo'); +-- Transaction Group #3 CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_invite_created_invited ON invite ("createdAt", "invitedBy"); +-- Transaction Group #4 +-- pgschema:wait SELECT COALESCE(i.indisvalid, false) as done, CASE WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total ELSE 0 END as progress -FROM pg_stat_progress_create_index p -LEFT JOIN pg_class c ON p.relid = c.oid -LEFT JOIN pg_indexes idx ON idx.tablename = c.relname -LEFT JOIN pg_class ic ON ic.relname = idx.indexname -LEFT JOIN pg_index i ON i.indexrelid = ic.oid -WHERE idx.indexname = 'idx_invite_created_invited' OR p.index_relid = ic.oid; \ No newline at end of file +FROM pg_class c +LEFT JOIN pg_index i ON c.oid = i.indexrelid +LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid +WHERE lower(c.relname) = lower('idx_invite_created_invited'); \ No newline at end of file From 3d80a4f8c00830ab7158089a75187c15cb66bc3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20R=C4=85czka?= <04_barista_pads@icloud.com> Date: Sat, 13 Sep 2025 18:30:02 +0200 Subject: [PATCH 3/3] fix: update wait queries in all online index tests All CREATE INDEX CONCURRENTLY tests now use lower() function in wait queries to properly handle case-insensitive index name comparisons in PostgreSQL --- testdata/diff/online/add_composite_index/plan.json | 2 +- testdata/diff/online/add_composite_index/plan.sql | 2 +- testdata/diff/online/add_composite_index/plan.txt | 2 +- testdata/diff/online/add_functional_index/plan.json | 2 +- testdata/diff/online/add_functional_index/plan.sql | 2 +- testdata/diff/online/add_functional_index/plan.txt | 2 +- testdata/diff/online/add_partial_index/plan.json | 2 +- testdata/diff/online/add_partial_index/plan.sql | 2 +- testdata/diff/online/add_partial_index/plan.txt | 2 +- .../diff/online/add_unique_multi_column_index/plan.json | 2 +- testdata/diff/online/add_unique_multi_column_index/plan.sql | 2 +- testdata/diff/online/add_unique_multi_column_index/plan.txt | 2 +- testdata/diff/online/alter_composite_index/plan.json | 4 ++-- testdata/diff/online/alter_composite_index/plan.sql | 4 ++-- testdata/diff/online/alter_composite_index/plan.txt | 6 +++--- 15 files changed, 19 insertions(+), 19 deletions(-) diff --git a/testdata/diff/online/add_composite_index/plan.json b/testdata/diff/online/add_composite_index/plan.json index 9b0327cb..64b7a9e3 100644 --- a/testdata/diff/online/add_composite_index/plan.json +++ b/testdata/diff/online/add_composite_index/plan.json @@ -19,7 +19,7 @@ { "steps": [ { - "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE c.relname = 'idx_users_email_status';", + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_users_email_status');", "directive": { "type": "wait", "message": "Creating index idx_users_email_status" diff --git a/testdata/diff/online/add_composite_index/plan.sql b/testdata/diff/online/add_composite_index/plan.sql index 037529e6..d2e722ee 100644 --- a/testdata/diff/online/add_composite_index/plan.sql +++ b/testdata/diff/online/add_composite_index/plan.sql @@ -10,4 +10,4 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_users_email_status'; +WHERE lower(c.relname) = lower('idx_users_email_status'); diff --git a/testdata/diff/online/add_composite_index/plan.txt b/testdata/diff/online/add_composite_index/plan.txt index 2b0d7b11..0ce65a75 100644 --- a/testdata/diff/online/add_composite_index/plan.txt +++ b/testdata/diff/online/add_composite_index/plan.txt @@ -24,4 +24,4 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_users_email_status'; +WHERE lower(c.relname) = lower('idx_users_email_status'); \ No newline at end of file diff --git a/testdata/diff/online/add_functional_index/plan.json b/testdata/diff/online/add_functional_index/plan.json index 48d72f66..1db75e5a 100644 --- a/testdata/diff/online/add_functional_index/plan.json +++ b/testdata/diff/online/add_functional_index/plan.json @@ -19,7 +19,7 @@ { "steps": [ { - "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE c.relname = 'idx_users_fullname_search';", + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_users_fullname_search');", "directive": { "type": "wait", "message": "Creating index idx_users_fullname_search" diff --git a/testdata/diff/online/add_functional_index/plan.sql b/testdata/diff/online/add_functional_index/plan.sql index 9837516d..4a816674 100644 --- a/testdata/diff/online/add_functional_index/plan.sql +++ b/testdata/diff/online/add_functional_index/plan.sql @@ -10,4 +10,4 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_users_fullname_search'; +WHERE lower(c.relname) = lower('idx_users_fullname_search'); diff --git a/testdata/diff/online/add_functional_index/plan.txt b/testdata/diff/online/add_functional_index/plan.txt index d6f63a8c..c42a9d7c 100644 --- a/testdata/diff/online/add_functional_index/plan.txt +++ b/testdata/diff/online/add_functional_index/plan.txt @@ -24,4 +24,4 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_users_fullname_search'; +WHERE lower(c.relname) = lower('idx_users_fullname_search'); \ No newline at end of file diff --git a/testdata/diff/online/add_partial_index/plan.json b/testdata/diff/online/add_partial_index/plan.json index 3a7ec6d8..bb9cc88c 100644 --- a/testdata/diff/online/add_partial_index/plan.json +++ b/testdata/diff/online/add_partial_index/plan.json @@ -19,7 +19,7 @@ { "steps": [ { - "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE c.relname = 'idx_active_orders_customer_date';", + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_active_orders_customer_date');", "directive": { "type": "wait", "message": "Creating index idx_active_orders_customer_date" diff --git a/testdata/diff/online/add_partial_index/plan.sql b/testdata/diff/online/add_partial_index/plan.sql index b700201a..f474460d 100644 --- a/testdata/diff/online/add_partial_index/plan.sql +++ b/testdata/diff/online/add_partial_index/plan.sql @@ -10,4 +10,4 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_active_orders_customer_date'; +WHERE lower(c.relname) = lower('idx_active_orders_customer_date'); diff --git a/testdata/diff/online/add_partial_index/plan.txt b/testdata/diff/online/add_partial_index/plan.txt index fb584ad7..1d7cfc3b 100644 --- a/testdata/diff/online/add_partial_index/plan.txt +++ b/testdata/diff/online/add_partial_index/plan.txt @@ -24,4 +24,4 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_active_orders_customer_date'; +WHERE lower(c.relname) = lower('idx_active_orders_customer_date'); \ No newline at end of file diff --git a/testdata/diff/online/add_unique_multi_column_index/plan.json b/testdata/diff/online/add_unique_multi_column_index/plan.json index 2e446585..405eb649 100644 --- a/testdata/diff/online/add_unique_multi_column_index/plan.json +++ b/testdata/diff/online/add_unique_multi_column_index/plan.json @@ -19,7 +19,7 @@ { "steps": [ { - "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE c.relname = 'idx_unique_email_org';", + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_unique_email_org');", "directive": { "type": "wait", "message": "Creating index idx_unique_email_org" diff --git a/testdata/diff/online/add_unique_multi_column_index/plan.sql b/testdata/diff/online/add_unique_multi_column_index/plan.sql index 68d55c81..81024286 100644 --- a/testdata/diff/online/add_unique_multi_column_index/plan.sql +++ b/testdata/diff/online/add_unique_multi_column_index/plan.sql @@ -10,4 +10,4 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_unique_email_org'; +WHERE lower(c.relname) = lower('idx_unique_email_org'); diff --git a/testdata/diff/online/add_unique_multi_column_index/plan.txt b/testdata/diff/online/add_unique_multi_column_index/plan.txt index 7a0d4e44..b3f55201 100644 --- a/testdata/diff/online/add_unique_multi_column_index/plan.txt +++ b/testdata/diff/online/add_unique_multi_column_index/plan.txt @@ -24,4 +24,4 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_unique_email_org'; +WHERE lower(c.relname) = lower('idx_unique_email_org'); \ No newline at end of file diff --git a/testdata/diff/online/alter_composite_index/plan.json b/testdata/diff/online/alter_composite_index/plan.json index a82dfe31..fcd500b1 100644 --- a/testdata/diff/online/alter_composite_index/plan.json +++ b/testdata/diff/online/alter_composite_index/plan.json @@ -19,7 +19,7 @@ { "steps": [ { - "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE c.relname = 'idx_users_email_pgschema_new';", + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_users_email_pgschema_new');", "directive": { "type": "wait", "message": "Creating index idx_users_email_pgschema_new" @@ -59,7 +59,7 @@ { "steps": [ { - "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE c.relname = 'idx_users_status_pgschema_new';", + "sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE lower(c.relname) = lower('idx_users_status_pgschema_new');", "directive": { "type": "wait", "message": "Creating index idx_users_status_pgschema_new" diff --git a/testdata/diff/online/alter_composite_index/plan.sql b/testdata/diff/online/alter_composite_index/plan.sql index ad3cfc49..260be168 100644 --- a/testdata/diff/online/alter_composite_index/plan.sql +++ b/testdata/diff/online/alter_composite_index/plan.sql @@ -10,7 +10,7 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_users_email_pgschema_new'; +WHERE lower(c.relname) = lower('idx_users_email_pgschema_new'); DROP INDEX idx_users_email; @@ -28,7 +28,7 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_users_status_pgschema_new'; +WHERE lower(c.relname) = lower('idx_users_status_pgschema_new'); DROP INDEX idx_users_status; diff --git a/testdata/diff/online/alter_composite_index/plan.txt b/testdata/diff/online/alter_composite_index/plan.txt index c4f093df..d1eecbe4 100644 --- a/testdata/diff/online/alter_composite_index/plan.txt +++ b/testdata/diff/online/alter_composite_index/plan.txt @@ -25,7 +25,7 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_users_email_pgschema_new'; +WHERE lower(c.relname) = lower('idx_users_email_pgschema_new'); -- Transaction Group #3 DROP INDEX idx_users_email; @@ -46,9 +46,9 @@ SELECT FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indexrelid LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid -WHERE c.relname = 'idx_users_status_pgschema_new'; +WHERE lower(c.relname) = lower('idx_users_status_pgschema_new'); -- Transaction Group #6 DROP INDEX idx_users_status; -ALTER INDEX idx_users_status_pgschema_new RENAME TO idx_users_status; +ALTER INDEX idx_users_status_pgschema_new RENAME TO idx_users_status; \ No newline at end of file