Skip to content

Commit

Permalink
Add support for column identities (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
bplunkett-stripe committed Sep 3, 2024
1 parent 4f16804 commit ba73d0a
Show file tree
Hide file tree
Showing 9 changed files with 592 additions and 99 deletions.
240 changes: 240 additions & 0 deletions internal/migration_acceptance_tests/column_cases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,42 @@ var columnAcceptanceTestCases = []acceptanceTestCase{
)
`},
},
{
name: "Add identity column - always no cycle",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
id INT PRIMARY KEY
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
id INT PRIMARY KEY,
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
},
{
name: "Add identity column - default cycle",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
id INT PRIMARY KEY
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
id INT PRIMARY KEY,
identity_always BIGINT GENERATED BY DEFAULT AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 CYCLE )
);
`,
},
},
{
name: "Delete one column",
oldSchemaDDL: []string{
Expand Down Expand Up @@ -925,6 +961,210 @@ var columnAcceptanceTestCases = []acceptanceTestCase{
diff.MigrationHazardTypeImpactsDatabasePerformance,
},
},
{
name: "Remove identity from column",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT
);
`,
},
},
{
name: "Add identity to column",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY
);
`,
},
},
{
name: "Alter identity type - to by default",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED BY DEFAULT AS IDENTITY ( MINVALUE 1 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
},
{
name: "Alter identity type - to always",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED BY DEFAULT AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 1 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
},
{
name: "Alter identity minvalue",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 1 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
},
{
name: "Alter identity maxvalue",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 90 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
},
{
name: "Alter identity start",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 6 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
},
{
name: "Alter identity increment",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 6 CACHE 5 NO CYCLE )
);
`,
},
},
{
name: "Alter identity cache",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 6 NO CYCLE )
);
`,
},
},
{
name: "Alter identity cycle - to cycle",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 CYCLE )
);
`,
},
},
{
name: "Alter identity cycle - to no cycle",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
},
{
name: "Alter all identity properties (from always to default, from no cycle to cycle)",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE )
);
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
identity_always BIGINT GENERATED BY DEFAULT AS IDENTITY ( MINVALUE 1 MAXVALUE 90 START 30 INCREMENT 40 CACHE 50 CYCLE )
);
`,
},
},
}

func (suite *acceptanceTestSuite) TestColumnTestCases() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var partitionedTableAcceptanceTestCases = []acceptanceTestCase{
foo VARCHAR(255),
bar TEXT COLLATE "POSIX",
fizz SERIAL,
identity BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
CHECK ( fizz > 0 ),
PRIMARY KEY (foo, id),
UNIQUE (foo, bar)
Expand Down Expand Up @@ -58,6 +59,7 @@ var partitionedTableAcceptanceTestCases = []acceptanceTestCase{
foo VARCHAR(255),
bar TEXT COLLATE "POSIX",
fizz SERIAL,
identity BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
CHECK ( fizz > 0 ),
PRIMARY KEY (foo, id),
UNIQUE (foo, bar)
Expand Down Expand Up @@ -114,6 +116,7 @@ var partitionedTableAcceptanceTestCases = []acceptanceTestCase{
foo VARCHAR(255),
bar TEXT COLLATE "POSIX" NOT NULL DEFAULT 'some default',
fizz SERIAL,
identity BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
CHECK ( fizz > 0 ),
PRIMARY KEY (foo, id),
UNIQUE (foo, bar)
Expand All @@ -140,40 +143,6 @@ var partitionedTableAcceptanceTestCases = []acceptanceTestCase{
CREATE UNIQUE INDEX foobar_2_local_unique_idx ON schema_2.foobar_2(foo);
`,
},

expectedDBSchemaDDL: []string{`
CREATE SCHEMA schema_1;
CREATE TABLE schema_1."Foobar"(
id INT,
foo VARCHAR(255),
bar TEXT COLLATE "POSIX" NOT NULL DEFAULT 'some default',
fizz SERIAL,
CHECK ( fizz > 0 ),
PRIMARY KEY (foo, id),
UNIQUE (foo, bar)
) PARTITION BY LIST (foo);
ALTER TABLE schema_1."Foobar" REPLICA IDENTITY FULL;
ALTER TABLE schema_1."Foobar" ENABLE ROW LEVEL SECURITY;
ALTER TABLE schema_1."Foobar" FORCE ROW LEVEL SECURITY;
-- partitions
CREATE SCHEMA schema_2;
CREATE TABLE schema_2."FOOBAR_1" PARTITION OF schema_1."Foobar"(
foo NOT NULL,
bar NOT NULL
) FOR VALUES IN ('foo_1');
ALTER TABLE schema_2."FOOBAR_1" REPLICA IDENTITY NOTHING ;
CREATE TABLE schema_2.foobar_2 PARTITION OF schema_1."Foobar" FOR VALUES IN ('foo_2');
ALTER TABLE schema_2.foobar_2 REPLICA IDENTITY FULL;
CREATE TABLE schema_2.foobar_3 PARTITION OF schema_1."Foobar" FOR VALUES IN ('foo_3');
-- partitioned indexes
CREATE UNIQUE INDEX foobar_unique_idx ON schema_1."Foobar"(foo, fizz);
-- local indexes
CREATE INDEX foobar_1_local_idx ON schema_2."FOOBAR_1"(foo);
CREATE UNIQUE INDEX foobar_2_local_unique_idx ON schema_2.foobar_2(foo);
`,
},
},
{
name: "Create partitioned table with local primary keys and RLS enabled locally",
Expand Down
4 changes: 4 additions & 0 deletions internal/migration_acceptance_tests/schema_cases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var schemaAcceptanceTests = []acceptanceTestCase{
bar SERIAL NOT NULL,
fizz TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
color schema_1.color DEFAULT 'green',
quux BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
PRIMARY KEY (foo, id),
UNIQUE (foo, bar)
) PARTITION BY LIST(foo);
Expand Down Expand Up @@ -123,6 +124,7 @@ var schemaAcceptanceTests = []acceptanceTestCase{
bar SERIAL NOT NULL,
fizz TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
color schema_1.color DEFAULT 'green',
quux BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
PRIMARY KEY (foo, id),
UNIQUE (foo, bar)
) PARTITION BY LIST(foo);
Expand Down Expand Up @@ -211,6 +213,7 @@ var schemaAcceptanceTests = []acceptanceTestCase{
foo VARCHAR(255) DEFAULT 'some default' NOT NULL,
fizz TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
color schema_1.color DEFAULT 'green',
quux BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
UNIQUE (foo, bar)
);
CREATE INDEX foobar_normal_idx ON foobar USING hash (fizz);
Expand Down Expand Up @@ -292,6 +295,7 @@ var schemaAcceptanceTests = []acceptanceTestCase{
new_color new_color DEFAULT 'cyan',
new_bar SMALLSERIAL NOT NULL,
new_foo VARCHAR(255) DEFAULT '' NOT NULL CHECK ( new_foo IS NOT NULL),
new_quux BIGINT GENERATED BY DEFAULT AS IDENTITY ( MINVALUE 20 MAXVALUE 90 START 30 INCREMENT 40 CACHE 50 CYCLE ),
UNIQUE (new_foo, new_bar)
);
ALTER TABLE "New_table" ADD CONSTRAINT "new_fzz_check" CHECK ( new_fizz < CURRENT_TIMESTAMP - interval '1 month' ) NO INHERIT NOT VALID;
Expand Down
12 changes: 9 additions & 3 deletions internal/migration_acceptance_tests/table_cases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ var tableAcceptanceTestCases = []acceptanceTestCase{
foo VARCHAR(255) COLLATE "POSIX" DEFAULT '' NOT NULL,
bar TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
fizz SERIAL NOT NULL UNIQUE ,
buzz REAL CHECK (buzz IS NOT NULL)
buzz REAL CHECK (buzz IS NOT NULL),
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
identity_default BIGINT GENERATED BY DEFAULT AS IDENTITY ( MINVALUE 20 MAXVALUE 90 START 30 INCREMENT 40 CACHE 50 CYCLE )
);
ALTER TABLE foobar REPLICA IDENTITY FULL;
ALTER TABLE foobar ENABLE ROW LEVEL SECURITY;
Expand All @@ -39,7 +41,9 @@ var tableAcceptanceTestCases = []acceptanceTestCase{
foo VARCHAR(255) COLLATE "POSIX" DEFAULT '' NOT NULL,
bar TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
fizz SERIAL NOT NULL UNIQUE,
buzz REAL CHECK (buzz IS NOT NULL)
buzz REAL CHECK (buzz IS NOT NULL),
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
identity_default BIGINT GENERATED BY DEFAULT AS IDENTITY ( MINVALUE 20 MAXVALUE 90 START 30 INCREMENT 40 CACHE 50 CYCLE )
);
ALTER TABLE foobar REPLICA IDENTITY FULL;
ALTER TABLE foobar ENABLE ROW LEVEL SECURITY;
Expand Down Expand Up @@ -70,7 +74,9 @@ var tableAcceptanceTestCases = []acceptanceTestCase{
foo VARCHAR(255) COLLATE "POSIX" DEFAULT '' NOT NULL,
bar TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
fizz SERIAL NOT NULL UNIQUE,
buzz REAL CHECK (buzz IS NOT NULL)
buzz REAL CHECK (buzz IS NOT NULL),
identity_always BIGINT GENERATED ALWAYS AS IDENTITY ( MINVALUE 2 MAXVALUE 9 START 3 INCREMENT 4 CACHE 5 NO CYCLE ),
identity_default BIGINT GENERATED BY DEFAULT AS IDENTITY ( MINVALUE 20 MAXVALUE 90 START 30 INCREMENT 40 CACHE 50 CYCLE )
);
ALTER TABLE foobar REPLICA IDENTITY FULL;
ALTER TABLE foobar ENABLE ROW LEVEL SECURITY;
Expand Down
Loading

0 comments on commit ba73d0a

Please sign in to comment.