From d5cc3a8c1dd9c980d3bbbdfc24ba9c0ea5fc03c6 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 19 Jan 2024 15:00:14 +0900 Subject: [PATCH v6 3/8] Integrate addition of attributes for sequences with ALTER TABLE This is a process similar to CREATE OR REPLACE VIEW, where attributes are added to a sequence after the initial creation of its Relation. This gives more flexibility to sequence AMs, as these may want to force their own set of attributes to use when coupled with their computation methods and/or underlying table AM. --- src/include/nodes/parsenodes.h | 1 + src/backend/commands/sequence.c | 29 +++++++++++++++++-- src/backend/commands/tablecmds.c | 10 +++++++ src/backend/tcop/utility.c | 4 +++ .../test_ddl_deparse/expected/alter_table.out | 10 +++++-- .../expected/create_sequence_1.out | 5 +++- .../expected/create_table.out | 15 ++++++++-- .../test_ddl_deparse/test_ddl_deparse.c | 3 ++ 8 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 85a62b538e..6823f595ae 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2351,6 +2351,7 @@ typedef struct AlterTableStmt typedef enum AlterTableType { AT_AddColumn, /* add column */ + AT_AddColumnToSequence, /* implicitly via CREATE SEQUENCE */ AT_AddColumnToView, /* implicitly via CREATE OR REPLACE VIEW */ AT_ColumnDefault, /* alter column default */ AT_CookedColumnDefault, /* add a pre-cooked column default */ diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 5bc7a74d5f..33832d9fa8 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -136,6 +136,9 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) TupleDesc tupDesc; Datum value[SEQ_COL_LASTCOL]; bool null[SEQ_COL_LASTCOL]; + List *elts = NIL; + List *atcmds = NIL; + ListCell *lc; Datum pgs_values[Natts_pg_sequence]; bool pgs_nulls[Natts_pg_sequence]; int i; @@ -174,7 +177,6 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) /* * Create relation (and fill value[] and null[] for the tuple) */ - stmt->tableElts = NIL; for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++) { ColumnDef *coldef = NULL; @@ -198,7 +200,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) coldef->is_not_null = true; null[i - 1] = false; - stmt->tableElts = lappend(stmt->tableElts, coldef); + elts = lappend(elts, coldef); } stmt->relation = seq->sequence; @@ -208,12 +210,35 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) stmt->oncommit = ONCOMMIT_NOOP; stmt->tablespacename = NULL; stmt->if_not_exists = seq->if_not_exists; + /* + * Initial relation has no attributes, these are added later. + */ + stmt->tableElts = NIL; address = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId, NULL, NULL); seqoid = address.objectId; Assert(seqoid != InvalidOid); rel = sequence_open(seqoid, AccessExclusiveLock); + + /* Add all the attributes to the sequence */ + foreach(lc, elts) + { + AlterTableCmd *atcmd; + + atcmd = makeNode(AlterTableCmd); + atcmd->subtype = AT_AddColumnToSequence; + atcmd->def = (Node *) lfirst(lc); + atcmds = lappend(atcmds, atcmd); + } + + /* + * No recursion needed. Note that EventTriggerAlterTableStart() should + * have been called. + */ + AlterTableInternal(RelationGetRelid(rel), atcmds, false); + CommandCounterIncrement(); + tupDesc = RelationGetDescr(rel); /* now initialize the sequence's data */ diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 66cda26a25..4d42ee442b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -4491,6 +4491,7 @@ AlterTableGetLockLevel(List *cmds) * Subcommands that may be visible to concurrent SELECTs */ case AT_DropColumn: /* change visible to SELECT */ + case AT_AddColumnToSequence: /* CREATE SEQUENCE */ case AT_AddColumnToView: /* CREATE VIEW */ case AT_DropOids: /* used to equiv to DropColumn */ case AT_EnableAlwaysRule: /* may change SELECT rules */ @@ -4802,6 +4803,13 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, /* Recursion occurs during execution phase */ pass = AT_PASS_ADD_COL; break; + case AT_AddColumnToSequence: /* add column via CREATE SEQUENCE */ + ATSimplePermissions(cmd->subtype, rel, ATT_SEQUENCE); + ATPrepAddColumn(wqueue, rel, recurse, recursing, false, cmd, + lockmode, context); + /* Recursion occurs during execution phase */ + pass = AT_PASS_ADD_COL; + break; case AT_AddColumnToView: /* add column via CREATE OR REPLACE VIEW */ ATSimplePermissions(cmd->subtype, rel, ATT_VIEW); ATPrepAddColumn(wqueue, rel, recurse, recursing, true, cmd, @@ -5227,6 +5235,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, switch (cmd->subtype) { case AT_AddColumn: /* ADD COLUMN */ + case AT_AddColumnToSequence: /* add column via CREATE SEQUENCE */ case AT_AddColumnToView: /* add column via CREATE OR REPLACE VIEW */ address = ATExecAddColumn(wqueue, tab, rel, &cmd, cmd->recurse, false, @@ -6404,6 +6413,7 @@ alter_table_type_to_string(AlterTableType cmdtype) switch (cmdtype) { case AT_AddColumn: + case AT_AddColumnToSequence: case AT_AddColumnToView: return "ADD COLUMN"; case AT_ColumnDefault: diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index fa66b8017e..b64acfb23f 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1664,7 +1664,11 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_CreateSeqStmt: + EventTriggerAlterTableStart(parsetree); address = DefineSequence(pstate, (CreateSeqStmt *) parsetree); + /* stashed internally */ + commandCollected = true; + EventTriggerAlterTableEnd(); break; case T_AlterSeqStmt: diff --git a/src/test/modules/test_ddl_deparse/expected/alter_table.out b/src/test/modules/test_ddl_deparse/expected/alter_table.out index 6daa186a84..24b2179455 100644 --- a/src/test/modules/test_ddl_deparse/expected/alter_table.out +++ b/src/test/modules/test_ddl_deparse/expected/alter_table.out @@ -25,7 +25,10 @@ NOTICE: DDL test: type simple, tag CREATE TABLE CREATE TABLE grandchild () INHERITS (child); NOTICE: DDL test: type simple, tag CREATE TABLE ALTER TABLE parent ADD COLUMN b serial; -NOTICE: DDL test: type simple, tag CREATE SEQUENCE +NOTICE: DDL test: type alter table, tag CREATE SEQUENCE +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column last_value of sequence parent_b_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column log_cnt of sequence parent_b_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column is_called of sequence parent_b_seq NOTICE: DDL test: type alter table, tag ALTER TABLE NOTICE: subcommand: type ADD COLUMN (and recurse) desc column b of table parent NOTICE: DDL test: type simple, tag ALTER SEQUENCE @@ -76,7 +79,10 @@ NOTICE: subcommand: type SET NOT NULL desc column a of table parent NOTICE: subcommand: type SET NOT NULL desc column a of table child NOTICE: subcommand: type SET NOT NULL desc column a of table grandchild ALTER TABLE parent ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; -NOTICE: DDL test: type simple, tag CREATE SEQUENCE +NOTICE: DDL test: type alter table, tag CREATE SEQUENCE +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column last_value of sequence parent_a_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column log_cnt of sequence parent_a_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column is_called of sequence parent_a_seq NOTICE: DDL test: type simple, tag ALTER SEQUENCE NOTICE: DDL test: type alter table, tag ALTER TABLE NOTICE: subcommand: type ADD IDENTITY (and recurse) desc column a of table parent diff --git a/src/test/modules/test_ddl_deparse/expected/create_sequence_1.out b/src/test/modules/test_ddl_deparse/expected/create_sequence_1.out index 5837ea484e..310ce5a6ba 100644 --- a/src/test/modules/test_ddl_deparse/expected/create_sequence_1.out +++ b/src/test/modules/test_ddl_deparse/expected/create_sequence_1.out @@ -8,4 +8,7 @@ CREATE SEQUENCE fkey_table_seq START 10 CACHE 10 CYCLE; -NOTICE: DDL test: type simple, tag CREATE SEQUENCE +NOTICE: DDL test: type alter table, tag CREATE SEQUENCE +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column last_value of sequence fkey_table_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column log_cnt of sequence fkey_table_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column is_called of sequence fkey_table_seq diff --git a/src/test/modules/test_ddl_deparse/expected/create_table.out b/src/test/modules/test_ddl_deparse/expected/create_table.out index 2178ce83e9..2be95f99f8 100644 --- a/src/test/modules/test_ddl_deparse/expected/create_table.out +++ b/src/test/modules/test_ddl_deparse/expected/create_table.out @@ -50,9 +50,18 @@ CREATE TABLE datatype_table ( PRIMARY KEY (id), UNIQUE (id_big) ); -NOTICE: DDL test: type simple, tag CREATE SEQUENCE -NOTICE: DDL test: type simple, tag CREATE SEQUENCE -NOTICE: DDL test: type simple, tag CREATE SEQUENCE +NOTICE: DDL test: type alter table, tag CREATE SEQUENCE +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column last_value of sequence datatype_table_id_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column log_cnt of sequence datatype_table_id_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column is_called of sequence datatype_table_id_seq +NOTICE: DDL test: type alter table, tag CREATE SEQUENCE +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column last_value of sequence datatype_table_id_big_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column log_cnt of sequence datatype_table_id_big_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column is_called of sequence datatype_table_id_big_seq +NOTICE: DDL test: type alter table, tag CREATE SEQUENCE +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column last_value of sequence datatype_table_is_small_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column log_cnt of sequence datatype_table_is_small_seq +NOTICE: subcommand: type ADD COLUMN TO SEQUENCE desc column is_called of sequence datatype_table_is_small_seq NOTICE: DDL test: type simple, tag CREATE TABLE NOTICE: DDL test: type simple, tag CREATE INDEX NOTICE: DDL test: type simple, tag CREATE INDEX diff --git a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c index 67ff2b6367..61236a6343 100644 --- a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c +++ b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c @@ -114,6 +114,9 @@ get_altertable_subcmdinfo(PG_FUNCTION_ARGS) case AT_AddColumn: strtype = "ADD COLUMN"; break; + case AT_AddColumnToSequence: + strtype = "ADD COLUMN TO SEQUENCE"; + break; case AT_AddColumnToView: strtype = "ADD COLUMN TO VIEW"; break; -- 2.45.1