diff --git a/ir/queries/queries.sql b/ir/queries/queries.sql index 213bea58..2e149b84 100644 --- a/ir/queries/queries.sql +++ b/ir/queries/queries.sql @@ -83,20 +83,20 @@ WITH column_base AS ( -- for non-array fixed-length types like name (typelem points to char). -- Use format_type to preserve typmod for element types (e.g., varchar(128)[] for character varying(128)[]) CASE - WHEN en.nspname = 'pg_catalog' THEN et.typname + WHEN en.nspname = 'pg_catalog' THEN et.typname::text ELSE quote_ident(en.nspname) || '.' || quote_ident(et.typname) END || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') || '[]' WHEN dt.typtype = 'b' THEN -- Non-array base types: qualify if not in pg_catalog or table's schema -- Use format_type to preserve typmod for extension types (e.g., vector(384) for pgvector) CASE - WHEN dn.nspname = 'pg_catalog' THEN c.udt_name + WHEN dn.nspname = 'pg_catalog' THEN c.udt_name::text WHEN dn.nspname = c.table_schema THEN - dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') + dt.typname::text || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') ELSE - dn.nspname || '.' || dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') + dn.nspname::text || '.' || dt.typname::text || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') END - ELSE c.udt_name + ELSE c.udt_name::text END AS resolved_type, c.is_identity, c.identity_generation, @@ -197,20 +197,20 @@ WITH column_base AS ( -- for non-array fixed-length types like name (typelem points to char). -- Use format_type to preserve typmod for element types (e.g., varchar(128)[] for character varying(128)[]) CASE - WHEN en.nspname = 'pg_catalog' THEN et.typname + WHEN en.nspname = 'pg_catalog' THEN et.typname::text ELSE quote_ident(en.nspname) || '.' || quote_ident(et.typname) END || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') || '[]' WHEN dt.typtype = 'b' THEN -- Non-array base types: qualify if not in pg_catalog or table's schema -- Use format_type to preserve typmod for extension types (e.g., vector(384) for pgvector) CASE - WHEN dn.nspname = 'pg_catalog' THEN c.udt_name + WHEN dn.nspname = 'pg_catalog' THEN c.udt_name::text WHEN dn.nspname = c.table_schema THEN - dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') + dt.typname::text || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') ELSE - dn.nspname || '.' || dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') + dn.nspname::text || '.' || dt.typname::text || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') END - ELSE c.udt_name + ELSE c.udt_name::text END AS resolved_type, c.is_identity, c.identity_generation, @@ -620,7 +620,7 @@ SELECT format_type(a.aggtranstype, NULL) WHEN stt.typcategory = 'A' THEN CASE - WHEN sten.nspname = 'pg_catalog' THEN stet.typname + WHEN sten.nspname = 'pg_catalog' THEN stet.typname::text ELSE quote_ident(sten.nspname) || '.' || quote_ident(stet.typname) END || COALESCE(substring(format_type(a.aggtranstype, NULL) FROM '\([^)]*\)'), '') || '[]' ELSE quote_ident(stn.nspname) || '.' || quote_ident(stt.typname) @@ -722,7 +722,7 @@ SELECT format_type(a.atttypid, a.atttypmod) WHEN at.typcategory = 'A' THEN CASE - WHEN aen.nspname = 'pg_catalog' THEN aet.typname + WHEN aen.nspname = 'pg_catalog' THEN aet.typname::text ELSE quote_ident(aen.nspname) || '.' || quote_ident(aet.typname) END || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') || '[]' ELSE @@ -915,7 +915,7 @@ SELECT format_type(t.typbasetype, t.typtypmod) WHEN bt.typcategory = 'A' THEN CASE - WHEN ben.nspname = 'pg_catalog' THEN bet.typname + WHEN ben.nspname = 'pg_catalog' THEN bet.typname::text ELSE quote_ident(ben.nspname) || '.' || quote_ident(bet.typname) END || COALESCE(substring(format_type(t.typbasetype, t.typtypmod) FROM '\([^)]*\)'), '') || '[]' ELSE @@ -1203,7 +1203,7 @@ SELECT format_type(a.aggtranstype, NULL) WHEN stt.typcategory = 'A' THEN CASE - WHEN sten.nspname = 'pg_catalog' THEN stet.typname + WHEN sten.nspname = 'pg_catalog' THEN stet.typname::text ELSE quote_ident(sten.nspname) || '.' || quote_ident(stet.typname) END || COALESCE(substring(format_type(a.aggtranstype, NULL) FROM '\([^)]*\)'), '') || '[]' ELSE quote_ident(stn.nspname) || '.' || quote_ident(stt.typname) @@ -1238,7 +1238,7 @@ SELECT format_type(a.aggmtranstype, NULL) WHEN mstt.typcategory = 'A' THEN CASE - WHEN msten.nspname = 'pg_catalog' THEN mstet.typname + WHEN msten.nspname = 'pg_catalog' THEN mstet.typname::text ELSE quote_ident(msten.nspname) || '.' || quote_ident(mstet.typname) END || COALESCE(substring(format_type(a.aggmtranstype, NULL) FROM '\([^)]*\)'), '') || '[]' ELSE quote_ident(mstn.nspname) || '.' || quote_ident(mstt.typname) @@ -1414,7 +1414,7 @@ SELECT format_type(t.typbasetype, t.typtypmod) WHEN bt.typcategory = 'A' THEN CASE - WHEN ben.nspname = 'pg_catalog' THEN bet.typname + WHEN ben.nspname = 'pg_catalog' THEN bet.typname::text ELSE quote_ident(ben.nspname) || '.' || quote_ident(bet.typname) END || COALESCE(substring(format_type(t.typbasetype, t.typtypmod) FROM '\([^)]*\)'), '') || '[]' ELSE @@ -1474,7 +1474,7 @@ SELECT format_type(a.atttypid, a.atttypmod) WHEN at.typcategory = 'A' THEN CASE - WHEN aen.nspname = 'pg_catalog' THEN aet.typname + WHEN aen.nspname = 'pg_catalog' THEN aet.typname::text ELSE quote_ident(aen.nspname) || '.' || quote_ident(aet.typname) END || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') || '[]' ELSE diff --git a/ir/queries/queries.sql.go b/ir/queries/queries.sql.go index e4dac1b2..a86937ca 100644 --- a/ir/queries/queries.sql.go +++ b/ir/queries/queries.sql.go @@ -28,7 +28,7 @@ SELECT format_type(a.aggtranstype, NULL) WHEN stt.typcategory = 'A' THEN CASE - WHEN sten.nspname = 'pg_catalog' THEN stet.typname + WHEN sten.nspname = 'pg_catalog' THEN stet.typname::text ELSE quote_ident(sten.nspname) || '.' || quote_ident(stet.typname) END || COALESCE(substring(format_type(a.aggtranstype, NULL) FROM '\([^)]*\)'), '') || '[]' ELSE quote_ident(stn.nspname) || '.' || quote_ident(stt.typname) @@ -132,7 +132,7 @@ SELECT format_type(a.aggtranstype, NULL) WHEN stt.typcategory = 'A' THEN CASE - WHEN sten.nspname = 'pg_catalog' THEN stet.typname + WHEN sten.nspname = 'pg_catalog' THEN stet.typname::text ELSE quote_ident(sten.nspname) || '.' || quote_ident(stet.typname) END || COALESCE(substring(format_type(a.aggtranstype, NULL) FROM '\([^)]*\)'), '') || '[]' ELSE quote_ident(stn.nspname) || '.' || quote_ident(stt.typname) @@ -167,7 +167,7 @@ SELECT format_type(a.aggmtranstype, NULL) WHEN mstt.typcategory = 'A' THEN CASE - WHEN msten.nspname = 'pg_catalog' THEN mstet.typname + WHEN msten.nspname = 'pg_catalog' THEN mstet.typname::text ELSE quote_ident(msten.nspname) || '.' || quote_ident(mstet.typname) END || COALESCE(substring(format_type(a.aggmtranstype, NULL) FROM '\([^)]*\)'), '') || '[]' ELSE quote_ident(mstn.nspname) || '.' || quote_ident(mstt.typname) @@ -398,20 +398,18 @@ WITH column_base AS ( -- for non-array fixed-length types like name (typelem points to char). -- Use format_type to preserve typmod for element types (e.g., varchar(128)[] for character varying(128)[]) CASE - WHEN en.nspname = 'pg_catalog' THEN et.typname + WHEN en.nspname = 'pg_catalog' THEN et.typname::text ELSE quote_ident(en.nspname) || '.' || quote_ident(et.typname) END || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') || '[]' WHEN dt.typtype = 'b' THEN - -- Non-array base types: qualify if not in pg_catalog or table's schema - -- Use format_type to preserve typmod for extension types (e.g., vector(384) for pgvector) CASE - WHEN dn.nspname = 'pg_catalog' THEN c.udt_name + WHEN dn.nspname = 'pg_catalog' THEN c.udt_name::text WHEN dn.nspname = c.table_schema THEN - dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') + dt.typname::text || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') ELSE - dn.nspname || '.' || dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') + dn.nspname::text || '.' || dt.typname::text || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') END - ELSE c.udt_name + ELSE c.udt_name::text END AS resolved_type, c.is_identity, c.identity_generation, @@ -579,25 +577,19 @@ WITH column_base AS ( WHEN dt.typtype = 'e' OR dt.typtype = 'c' THEN quote_ident(dn.nspname) || '.' || quote_ident(dt.typname) WHEN dt.typtype = 'b' AND dt.typcategory = 'A' THEN - -- Array types: apply same schema qualification logic to element type - -- Use typcategory = 'A' rather than typelem <> 0; the latter is true - -- for non-array fixed-length types like name (typelem points to char). - -- Use format_type to preserve typmod for element types (e.g., varchar(128)[] for character varying(128)[]) CASE - WHEN en.nspname = 'pg_catalog' THEN et.typname + WHEN en.nspname = 'pg_catalog' THEN et.typname::text ELSE quote_ident(en.nspname) || '.' || quote_ident(et.typname) END || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') || '[]' WHEN dt.typtype = 'b' THEN - -- Non-array base types: qualify if not in pg_catalog or table's schema - -- Use format_type to preserve typmod for extension types (e.g., vector(384) for pgvector) CASE - WHEN dn.nspname = 'pg_catalog' THEN c.udt_name + WHEN dn.nspname = 'pg_catalog' THEN c.udt_name::text WHEN dn.nspname = c.table_schema THEN - dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') + dt.typname::text || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') ELSE - dn.nspname || '.' || dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') + dn.nspname::text || '.' || dt.typname::text || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') END - ELSE c.udt_name + ELSE c.udt_name::text END AS resolved_type, c.is_identity, c.identity_generation, @@ -766,7 +758,7 @@ SELECT format_type(a.atttypid, a.atttypmod) WHEN at.typcategory = 'A' THEN CASE - WHEN aen.nspname = 'pg_catalog' THEN aet.typname + WHEN aen.nspname = 'pg_catalog' THEN aet.typname::text ELSE quote_ident(aen.nspname) || '.' || quote_ident(aet.typname) END || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') || '[]' ELSE @@ -840,7 +832,7 @@ SELECT format_type(a.atttypid, a.atttypmod) WHEN at.typcategory = 'A' THEN CASE - WHEN aen.nspname = 'pg_catalog' THEN aet.typname + WHEN aen.nspname = 'pg_catalog' THEN aet.typname::text ELSE quote_ident(aen.nspname) || '.' || quote_ident(aet.typname) END || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '') || '[]' ELSE @@ -1361,7 +1353,7 @@ SELECT format_type(t.typbasetype, t.typtypmod) WHEN bt.typcategory = 'A' THEN CASE - WHEN ben.nspname = 'pg_catalog' THEN bet.typname + WHEN ben.nspname = 'pg_catalog' THEN bet.typname::text ELSE quote_ident(ben.nspname) || '.' || quote_ident(bet.typname) END || COALESCE(substring(format_type(t.typbasetype, t.typtypmod) FROM '\([^)]*\)'), '') || '[]' ELSE @@ -1434,7 +1426,7 @@ SELECT format_type(t.typbasetype, t.typtypmod) WHEN bt.typcategory = 'A' THEN CASE - WHEN ben.nspname = 'pg_catalog' THEN bet.typname + WHEN ben.nspname = 'pg_catalog' THEN bet.typname::text ELSE quote_ident(ben.nspname) || '.' || quote_ident(bet.typname) END || COALESCE(substring(format_type(t.typbasetype, t.typtypmod) FROM '\([^)]*\)'), '') || '[]' ELSE diff --git a/testdata/diff/create_table/issue_521_enum_truncation/diff.sql b/testdata/diff/create_table/issue_521_enum_truncation/diff.sql new file mode 100644 index 00000000..305e1ade --- /dev/null +++ b/testdata/diff/create_table/issue_521_enum_truncation/diff.sql @@ -0,0 +1 @@ +ALTER TABLE user_status_log ADD COLUMN name text; diff --git a/testdata/diff/create_table/issue_521_enum_truncation/new.sql b/testdata/diff/create_table/issue_521_enum_truncation/new.sql new file mode 100644 index 00000000..67cc28f3 --- /dev/null +++ b/testdata/diff/create_table/issue_521_enum_truncation/new.sql @@ -0,0 +1,14 @@ +CREATE TYPE public.user_status_log_source_enum AS ENUM ('web', 'api', 'mobile'); + +CREATE TYPE public.document_document_type_enum AS ENUM ('invoice', 'receipt', 'contract'); + +CREATE TABLE public.user_status_log ( + id integer NOT NULL, + name text, + source public.user_status_log_source_enum NOT NULL +); + +CREATE TABLE public.document ( + id integer NOT NULL, + document_type public.document_document_type_enum NOT NULL +); diff --git a/testdata/diff/create_table/issue_521_enum_truncation/old.sql b/testdata/diff/create_table/issue_521_enum_truncation/old.sql new file mode 100644 index 00000000..e359518c --- /dev/null +++ b/testdata/diff/create_table/issue_521_enum_truncation/old.sql @@ -0,0 +1,13 @@ +CREATE TYPE public.user_status_log_source_enum AS ENUM ('web', 'api', 'mobile'); + +CREATE TYPE public.document_document_type_enum AS ENUM ('invoice', 'receipt', 'contract'); + +CREATE TABLE public.user_status_log ( + id integer NOT NULL, + source public.user_status_log_source_enum NOT NULL +); + +CREATE TABLE public.document ( + id integer NOT NULL, + document_type public.document_document_type_enum NOT NULL +); diff --git a/testdata/diff/create_table/issue_521_enum_truncation/plan.json b/testdata/diff/create_table/issue_521_enum_truncation/plan.json new file mode 100644 index 00000000..f7b55586 --- /dev/null +++ b/testdata/diff/create_table/issue_521_enum_truncation/plan.json @@ -0,0 +1,20 @@ +{ + "version": "1.0.0", + "pgschema_version": "1.12.1", + "created_at": "1970-01-01T00:00:00Z", + "source_fingerprint": { + "hash": "ef66f70cb989537b9ce9779481a72cdcc56f79563681e5fed5d11abfc1122519" + }, + "groups": [ + { + "steps": [ + { + "sql": "ALTER TABLE user_status_log ADD COLUMN name text;", + "type": "table.column", + "operation": "create", + "path": "public.user_status_log.name" + } + ] + } + ] +} diff --git a/testdata/diff/create_table/issue_521_enum_truncation/plan.sql b/testdata/diff/create_table/issue_521_enum_truncation/plan.sql new file mode 100644 index 00000000..305e1ade --- /dev/null +++ b/testdata/diff/create_table/issue_521_enum_truncation/plan.sql @@ -0,0 +1 @@ +ALTER TABLE user_status_log ADD COLUMN name text; diff --git a/testdata/diff/create_table/issue_521_enum_truncation/plan.txt b/testdata/diff/create_table/issue_521_enum_truncation/plan.txt new file mode 100644 index 00000000..f46383aa --- /dev/null +++ b/testdata/diff/create_table/issue_521_enum_truncation/plan.txt @@ -0,0 +1,13 @@ +Plan: 1 to modify. + +Summary by type: + tables: 1 to modify + +Tables: + ~ user_status_log + + name (column) + +DDL to be executed: +-------------------------------------------------- + +ALTER TABLE user_status_log ADD COLUMN name text;