Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions cmd/dump/dump_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,45 @@ func TestDumpCommand_Issue191FunctionProcedureOverload(t *testing.T) {
runExactMatchTest(t, "issue_191_function_procedure_overload")
}

// Reproduces a bug where a column declared as `name` is dumped as `char[]`.
// The inspector classifies any base type with pg_type.typelem <> 0 as an array,
// but the `name` type has typelem = 18 (the OID of "char") despite not being an array.
func TestDumpCommand_NameTypeNotDumpedAsCharArray(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test in short mode")
}

embeddedPG := testutil.SetupPostgres(t)
defer embeddedPG.Stop()

conn, host, port, dbname, user, password := testutil.ConnectToPostgres(t, embeddedPG)
defer conn.Close()

_, err := conn.ExecContext(context.Background(), `CREATE TABLE pgschema_name_repro (n name);`)
if err != nil {
t.Fatalf("Failed to create table: %v", err)
}

output, err := ExecuteDump(&DumpConfig{
Host: host,
Port: port,
DB: dbname,
User: user,
Password: password,
Schema: "public",
})
if err != nil {
t.Fatalf("Dump command failed: %v", err)
}

if strings.Contains(output, "char[]") {
t.Errorf("Dump output should not contain char[] for a name column.\nOutput:\n%s", output)
}
if !strings.Contains(output, "n name") {
t.Errorf("Dump output should contain `n name` column declaration.\nOutput:\n%s", output)
}
}

func TestDumpCommand_Issue318CrossSchemaComment(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test in short mode")
Expand Down
2 changes: 1 addition & 1 deletion ir/inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ func (i *Inspector) buildConstraints(ctx context.Context, schema *IR, targetSche
Type: cType,
Columns: []*ConstraintColumn{},
NoInherit: constraint.NoInherit,
IsTemporal: constraint.IsPeriod, // PG18 temporal constraint (WITHOUT OVERLAPS / PERIOD)
IsTemporal: constraint.IsPeriod.Bool, // PG18 temporal constraint (WITHOUT OVERLAPS / PERIOD)
}

// Handle foreign key references
Expand Down
8 changes: 6 additions & 2 deletions ir/queries/queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@ WITH column_base AS (
CASE WHEN dn.nspname = c.table_schema THEN dt.typname
ELSE dn.nspname || '.' || dt.typname
END
WHEN dt.typtype = 'b' AND dt.typelem <> 0 THEN
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).
CASE
WHEN en.nspname = 'pg_catalog' THEN et.typname || '[]'
WHEN en.nspname = c.table_schema THEN et.typname || '[]'
Expand Down Expand Up @@ -195,8 +197,10 @@ WITH column_base AS (
CASE WHEN dn.nspname = c.table_schema THEN dt.typname
ELSE dn.nspname || '.' || dt.typname
END
WHEN dt.typtype = 'b' AND dt.typelem <> 0 THEN
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).
CASE
WHEN en.nspname = 'pg_catalog' THEN et.typname || '[]'
WHEN en.nspname = c.table_schema THEN et.typname || '[]'
Expand Down
132 changes: 68 additions & 64 deletions ir/queries/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.