On Tue, Jul 26, 2022 at 01:00:41PM +0000, houzj.f...@fujitsu.com wrote: > Thanks for the suggestion. I have removed the default and found some missed > subcommands in 0003 patch. Attach the new version patch here > (The 0001 and 0002 is unchanged).
I have reviewed what you have here, and I found that the change is too timid, with a coverage of 32% for test_ddl_deparse. Attached is an updated patch, that provides coverage for the most obvious cases I could see in tablecmds.c, bringing the coverage to 64% here. Some cases are straight-forward, like the four cases for RLS or the three subcases for RelOptions (where we'd better return an address even if doing doing for the replace case). Some cases that I have not included here would need more thoughts, like constraint validation and drop or even SET ACCESS METHOD, so I have discarded for now all the cases where we don't (or cannot) report properly an ObjectAddress yet. There is also a fancy case with DROP COLUMN, where we get an ObjectAddress referring to the column already dropped, aka roughly a ".....pg_dropped.N.....", and it is not like we should switch to only a reference of the table here because we want to know the name of the column dropped. I have discarded this last one as well, for now. All that could be expanded in more patches (triggers are an easy one), but what I have here is already a good cut. -- Michael
From a386086af62c661f0e41a8789266e0fc13579d83 Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@paquier.xyz> Date: Sat, 30 Jul 2022 15:54:38 +0900 Subject: [PATCH v4] Improve coverage for test_ddl_deparse --- src/backend/commands/tablecmds.c | 56 +++++--- .../test_ddl_deparse/expected/alter_table.out | 122 +++++++++++++++++- .../expected/create_table.out | 8 +- .../test_ddl_deparse/expected/create_view.out | 2 +- .../expected/test_ddl_deparse.out | 4 +- .../test_ddl_deparse/sql/alter_table.sql | 54 ++++++++ .../test_ddl_deparse/sql/test_ddl_deparse.sql | 4 +- .../test_ddl_deparse--1.0.sql | 6 +- .../test_ddl_deparse/test_ddl_deparse.c | 73 +++++++++-- 9 files changed, 279 insertions(+), 50 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index e7aef2f6b0..ef95332d95 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -576,7 +576,7 @@ static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, const char *tablespacename, LOCKMODE lockmode); static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode); static void ATExecSetTableSpaceNoStorage(Relation rel, Oid newTableSpace); -static void ATExecSetRelOptions(Relation rel, List *defList, +static ObjectAddress ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, LOCKMODE lockmode); static void ATExecEnableDisableTrigger(Relation rel, const char *trigname, @@ -592,8 +592,8 @@ static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKM static void ATExecDropOf(Relation rel, LOCKMODE lockmode); static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode); static void ATExecGenericOptions(Relation rel, List *options); -static void ATExecSetRowSecurity(Relation rel, bool rls); -static void ATExecForceNoForceRowSecurity(Relation rel, bool force_rls); +static ObjectAddress ATExecSetRowSecurity(Relation rel, bool rls); +static ObjectAddress ATExecForceNoForceRowSecurity(Relation rel, bool force_rls); static ObjectAddress ATExecSetCompression(Relation rel, const char *column, Node *newValue, LOCKMODE lockmode); @@ -5115,7 +5115,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, case AT_SetRelOptions: /* SET (...) */ case AT_ResetRelOptions: /* RESET (...) */ case AT_ReplaceRelOptions: /* replace entire option list */ - ATExecSetRelOptions(rel, (List *) cmd->def, cmd->subtype, lockmode); + address = ATExecSetRelOptions(rel, (List *) cmd->def, cmd->subtype, lockmode); break; case AT_EnableTrig: /* ENABLE TRIGGER name */ ATExecEnableDisableTrigger(rel, cmd->name, @@ -5183,16 +5183,16 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, ATExecReplicaIdentity(rel, (ReplicaIdentityStmt *) cmd->def, lockmode); break; case AT_EnableRowSecurity: - ATExecSetRowSecurity(rel, true); + address = ATExecSetRowSecurity(rel, true); break; case AT_DisableRowSecurity: - ATExecSetRowSecurity(rel, false); + address = ATExecSetRowSecurity(rel, false); break; case AT_ForceRowSecurity: - ATExecForceNoForceRowSecurity(rel, true); + address = ATExecForceNoForceRowSecurity(rel, true); break; case AT_NoForceRowSecurity: - ATExecForceNoForceRowSecurity(rel, false); + address = ATExecForceNoForceRowSecurity(rel, false); break; case AT_GenericOptions: ATExecGenericOptions(rel, (List *) cmd->def); @@ -5202,11 +5202,11 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, cur_pass, context); Assert(cmd != NULL); if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def, - context); + address = ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def, + context); else - ATExecAttachPartitionIdx(wqueue, rel, - ((PartitionCmd *) cmd->def)->name); + address = ATExecAttachPartitionIdx(wqueue, rel, + ((PartitionCmd *) cmd->def)->name); break; case AT_DetachPartition: cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode, @@ -5214,12 +5214,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Assert(cmd != NULL); /* ATPrepCmd ensures it must be a table */ Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - ATExecDetachPartition(wqueue, tab, rel, - ((PartitionCmd *) cmd->def)->name, - ((PartitionCmd *) cmd->def)->concurrent); + address = ATExecDetachPartition(wqueue, tab, rel, + ((PartitionCmd *) cmd->def)->name, + ((PartitionCmd *) cmd->def)->concurrent); break; case AT_DetachPartitionFinalize: - ATExecDetachPartitionFinalize(rel, ((PartitionCmd *) cmd->def)->name); + address = ATExecDetachPartitionFinalize(rel, ((PartitionCmd *) cmd->def)->name); break; default: /* oops */ elog(ERROR, "unrecognized alter table type: %d", @@ -14102,7 +14102,7 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, const char *tablespacen /* * Set, reset, or replace reloptions. */ -static void +static ObjectAddress ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, LOCKMODE lockmode) { @@ -14117,9 +14117,13 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; static char *validnsps[] = HEAP_RELOPT_NAMESPACES; + ObjectAddress address; if (defList == NIL && operation != AT_ReplaceRelOptions) - return; /* nothing to do */ + { + ObjectAddressSet(address, RelationRelationId, RelationGetRelid(rel)); + return address; /* nothing to do */ + } pgclass = table_open(RelationRelationId, RowExclusiveLock); @@ -14298,7 +14302,9 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, table_close(toastrel, NoLock); } + ObjectAddressSet(address, RelationRelationId, RelationGetRelid(rel)); table_close(pgclass, RowExclusiveLock); + return address; } /* @@ -15992,12 +15998,13 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode /* * ALTER TABLE ENABLE/DISABLE ROW LEVEL SECURITY */ -static void +static ObjectAddress ATExecSetRowSecurity(Relation rel, bool rls) { Relation pg_class; Oid relid; HeapTuple tuple; + ObjectAddress address; relid = RelationGetRelid(rel); @@ -16012,19 +16019,24 @@ ATExecSetRowSecurity(Relation rel, bool rls) ((Form_pg_class) GETSTRUCT(tuple))->relrowsecurity = rls; CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + ObjectAddressSet(address, RelationRelationId, relid); + table_close(pg_class, RowExclusiveLock); heap_freetuple(tuple); + + return address; } /* * ALTER TABLE FORCE/NO FORCE ROW LEVEL SECURITY */ -static void +static ObjectAddress ATExecForceNoForceRowSecurity(Relation rel, bool force_rls) { Relation pg_class; Oid relid; HeapTuple tuple; + ObjectAddress address; relid = RelationGetRelid(rel); @@ -16038,8 +16050,12 @@ ATExecForceNoForceRowSecurity(Relation rel, bool force_rls) ((Form_pg_class) GETSTRUCT(tuple))->relforcerowsecurity = force_rls; CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + ObjectAddressSet(address, RelationRelationId, relid); + table_close(pg_class, RowExclusiveLock); heap_freetuple(tuple); + + return address; } /* 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 141060fbdc..14151fe021 100644 --- a/src/test/modules/test_ddl_deparse/expected/alter_table.out +++ b/src/test/modules/test_ddl_deparse/expected/alter_table.out @@ -2,6 +2,18 @@ CREATE TABLE parent ( a int ); NOTICE: DDL test: type simple, tag CREATE TABLE +ALTER TABLE parent SET (fillfactor = 50); +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type SET RELOPTIONS desc table parent +ALTER TABLE parent RESET (fillfactor); +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type RESET RELOPTIONS desc table parent +CREATE INDEX parent_index ON parent(a); +NOTICE: DDL test: type simple, tag CREATE INDEX +ALTER TABLE parent CLUSTER ON parent_index; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type CLUSTER desc index parent_index +DROP INDEX parent_index; CREATE TABLE child () INHERITS (parent); NOTICE: DDL test: type simple, tag CREATE TABLE CREATE TABLE grandchild () INHERITS (child); @@ -9,21 +21,119 @@ 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 ALTER TABLE -NOTICE: subcommand: ADD COLUMN (and recurse) +NOTICE: subcommand: type ADD COLUMN (and recurse) desc column b of table parent NOTICE: DDL test: type simple, tag ALTER SEQUENCE ALTER TABLE parent RENAME COLUMN b TO c; NOTICE: DDL test: type simple, tag ALTER TABLE -ALTER TABLE parent ADD CONSTRAINT a_pos CHECK (a > 0); +-- Constraint, no recursion +ALTER TABLE ONLY grandchild ADD CONSTRAINT a_pos CHECK (a > 0); NOTICE: DDL test: type alter table, tag ALTER TABLE -NOTICE: subcommand: ADD CONSTRAINT (and recurse) +NOTICE: subcommand: type ADD CONSTRAINT desc constraint a_pos on table grandchild +-- Constraint, with recursion +ALTER TABLE parent ADD CONSTRAINT a_pos CHECK (a > 0); +NOTICE: merging constraint "a_pos" with inherited definition +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type ADD CONSTRAINT (and recurse) desc constraint a_pos on table parent CREATE TABLE part ( a int ) PARTITION BY RANGE (a); NOTICE: DDL test: type simple, tag CREATE TABLE CREATE TABLE part1 PARTITION OF part FOR VALUES FROM (1) to (100); NOTICE: DDL test: type simple, tag CREATE TABLE +CREATE TABLE part2 (a int); +NOTICE: DDL test: type simple, tag CREATE TABLE +ALTER TABLE part ATTACH PARTITION part2 FOR VALUES FROM (101) to (200); +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type ATTACH PARTITION desc table part2 +ALTER TABLE part DETACH PARTITION part2; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type DETACH PARTITION desc table part2 +DROP TABLE part2; ALTER TABLE part ADD PRIMARY KEY (a); NOTICE: DDL test: type alter table, tag ALTER TABLE -NOTICE: subcommand: SET NOT NULL -NOTICE: subcommand: SET NOT NULL -NOTICE: subcommand: ADD INDEX +NOTICE: subcommand: type SET NOT NULL desc column a of table part +NOTICE: subcommand: type SET NOT NULL desc column a of table part1 +NOTICE: subcommand: type ADD INDEX desc index part_pkey +ALTER TABLE parent ALTER COLUMN a SET NOT NULL; +NOTICE: DDL test: type alter table, tag ALTER TABLE +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 DROP NOT NULL; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type DROP NOT NULL desc column a of table parent +NOTICE: subcommand: type DROP NOT NULL desc column a of table child +NOTICE: subcommand: type DROP NOT NULL desc column a of table grandchild +ALTER TABLE parent ALTER COLUMN a SET NOT NULL; +NOTICE: DDL test: type alter table, tag ALTER TABLE +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 simple, tag ALTER SEQUENCE +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type ADD IDENTITY desc column a of table parent +ALTER TABLE parent ALTER COLUMN a SET GENERATED BY DEFAULT; +NOTICE: DDL test: type simple, tag ALTER SEQUENCE +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type SET IDENTITY desc column a of table parent +ALTER TABLE parent ALTER COLUMN a DROP IDENTITY; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type DROP IDENTITY desc column a of table parent +ALTER TABLE parent ALTER COLUMN a SET STATISTICS 100; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type SET STATS desc column a of table parent +NOTICE: subcommand: type SET STATS desc column a of table child +NOTICE: subcommand: type SET STATS desc column a of table grandchild +ALTER TABLE parent ALTER COLUMN a SET STORAGE PLAIN; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type SET STORAGE desc column a of table parent +NOTICE: subcommand: type SET STORAGE desc column a of table child +NOTICE: subcommand: type SET STORAGE desc column a of table grandchild +ALTER TABLE parent ENABLE ROW LEVEL SECURITY; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type ENABLE ROW SECURITY desc table parent +ALTER TABLE parent NO FORCE ROW LEVEL SECURITY; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type NO FORCE ROW SECURITY desc table parent +ALTER TABLE parent FORCE ROW LEVEL SECURITY; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type FORCE ROW SECURITY desc table parent +ALTER TABLE parent DISABLE ROW LEVEL SECURITY; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type DISABLE ROW SECURITY desc table parent +CREATE STATISTICS parent_stat (dependencies) ON a, c FROM parent; +NOTICE: DDL test: type simple, tag CREATE STATISTICS +ALTER TABLE parent ALTER COLUMN c TYPE numeric; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type ALTER COLUMN SET TYPE desc column c of table parent +NOTICE: subcommand: type ALTER COLUMN SET TYPE desc column c of table child +NOTICE: subcommand: type ALTER COLUMN SET TYPE desc column c of table grandchild +NOTICE: subcommand: type (re) ADD STATS desc statistics object parent_stat +ALTER TABLE parent ALTER COLUMN c SET DEFAULT 0; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type ALTER COLUMN SET DEFAULT desc column c of table parent +NOTICE: subcommand: type ALTER COLUMN SET DEFAULT desc column c of table child +NOTICE: subcommand: type ALTER COLUMN SET DEFAULT desc column c of table grandchild +CREATE TABLE tbl ( + a int generated always as (b::int * 2) stored, + b text +); +NOTICE: DDL test: type simple, tag CREATE TABLE +ALTER TABLE tbl ALTER COLUMN a DROP EXPRESSION; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type DROP EXPRESSION desc column a of table tbl +ALTER TABLE tbl ALTER COLUMN b SET COMPRESSION pglz; +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: type SET COMPRESSION desc column b of table tbl +CREATE TYPE comptype AS (r float8); +NOTICE: DDL test: type simple, tag CREATE TYPE +CREATE DOMAIN dcomptype AS comptype; +NOTICE: DDL test: type simple, tag CREATE DOMAIN +ALTER DOMAIN dcomptype ADD CONSTRAINT c1 check ((value).r > 0); +NOTICE: DDL test: type simple, tag ALTER DOMAIN +ALTER TYPE comptype ALTER ATTRIBUTE r TYPE bigint; +NOTICE: DDL test: type alter table, tag ALTER TYPE +NOTICE: subcommand: type ALTER COLUMN SET TYPE desc column r of composite type comptype +NOTICE: subcommand: type (re) ADD DOMAIN CONSTRAINT desc type dcomptype 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 0f2a2c164e..2178ce83e9 100644 --- a/src/test/modules/test_ddl_deparse/expected/create_table.out +++ b/src/test/modules/test_ddl_deparse/expected/create_table.out @@ -77,8 +77,8 @@ NOTICE: DDL test: type simple, tag CREATE TABLE NOTICE: DDL test: type simple, tag CREATE INDEX NOTICE: DDL test: type simple, tag CREATE INDEX NOTICE: DDL test: type alter table, tag ALTER TABLE -NOTICE: subcommand: ADD CONSTRAINT (and recurse) -NOTICE: subcommand: ADD CONSTRAINT (and recurse) +NOTICE: subcommand: type ADD CONSTRAINT (and recurse) desc constraint fkey_table_datatype_id_fkey on table fkey_table +NOTICE: subcommand: type ADD CONSTRAINT (and recurse) desc constraint fkey_big_id on table fkey_table -- Typed table CREATE TABLE employees OF employee_type ( PRIMARY KEY (name), @@ -86,7 +86,7 @@ CREATE TABLE employees OF employee_type ( ); NOTICE: DDL test: type simple, tag CREATE TABLE NOTICE: DDL test: type alter table, tag ALTER TABLE -NOTICE: subcommand: SET NOT NULL +NOTICE: subcommand: type SET NOT NULL desc column name of table employees NOTICE: DDL test: type simple, tag CREATE INDEX -- Inheritance CREATE TABLE person ( @@ -136,7 +136,7 @@ CREATE TABLE like_fkey_table ( ); NOTICE: DDL test: type simple, tag CREATE TABLE NOTICE: DDL test: type alter table, tag ALTER TABLE -NOTICE: subcommand: ALTER COLUMN SET DEFAULT (precooked) +NOTICE: subcommand: type ALTER COLUMN SET DEFAULT (precooked) desc column id of table like_fkey_table NOTICE: DDL test: type simple, tag CREATE INDEX NOTICE: DDL test: type simple, tag CREATE INDEX -- Volatile table types diff --git a/src/test/modules/test_ddl_deparse/expected/create_view.out b/src/test/modules/test_ddl_deparse/expected/create_view.out index 2ae4e2d225..cf5d711f99 100644 --- a/src/test/modules/test_ddl_deparse/expected/create_view.out +++ b/src/test/modules/test_ddl_deparse/expected/create_view.out @@ -8,7 +8,7 @@ CREATE OR REPLACE VIEW static_view AS SELECT 'bar'::TEXT AS col; NOTICE: DDL test: type simple, tag CREATE VIEW NOTICE: DDL test: type alter table, tag CREATE VIEW -NOTICE: subcommand: REPLACE RELOPTIONS +NOTICE: subcommand: type REPLACE RELOPTIONS desc view static_view CREATE VIEW datatype_view AS SELECT * FROM datatype_table; NOTICE: DDL test: type simple, tag CREATE VIEW diff --git a/src/test/modules/test_ddl_deparse/expected/test_ddl_deparse.out b/src/test/modules/test_ddl_deparse/expected/test_ddl_deparse.out index 4a5ea9e9ed..fc657ff49b 100644 --- a/src/test/modules/test_ddl_deparse/expected/test_ddl_deparse.out +++ b/src/test/modules/test_ddl_deparse/expected/test_ddl_deparse.out @@ -28,9 +28,9 @@ BEGIN -- if alter table, log more IF cmdtype = 'alter table' THEN FOR r2 IN SELECT * - FROM unnest(public.get_altertable_subcmdtypes(r.command)) + FROM public.get_altertable_subcmdinfo(r.command) LOOP - RAISE NOTICE ' subcommand: %', r2.unnest; + RAISE NOTICE ' subcommand: type % desc %', r2.cmdtype, r2.objdesc; END LOOP; END IF; END LOOP; diff --git a/src/test/modules/test_ddl_deparse/sql/alter_table.sql b/src/test/modules/test_ddl_deparse/sql/alter_table.sql index dec53a0640..24a5b9b3bf 100644 --- a/src/test/modules/test_ddl_deparse/sql/alter_table.sql +++ b/src/test/modules/test_ddl_deparse/sql/alter_table.sql @@ -2,6 +2,13 @@ CREATE TABLE parent ( a int ); +ALTER TABLE parent SET (fillfactor = 50); +ALTER TABLE parent RESET (fillfactor); + +CREATE INDEX parent_index ON parent(a); +ALTER TABLE parent CLUSTER ON parent_index; +DROP INDEX parent_index; + CREATE TABLE child () INHERITS (parent); CREATE TABLE grandchild () INHERITS (child); @@ -10,6 +17,9 @@ ALTER TABLE parent ADD COLUMN b serial; ALTER TABLE parent RENAME COLUMN b TO c; +-- Constraint, no recursion +ALTER TABLE ONLY grandchild ADD CONSTRAINT a_pos CHECK (a > 0); +-- Constraint, with recursion ALTER TABLE parent ADD CONSTRAINT a_pos CHECK (a > 0); CREATE TABLE part ( @@ -18,4 +28,48 @@ CREATE TABLE part ( CREATE TABLE part1 PARTITION OF part FOR VALUES FROM (1) to (100); +CREATE TABLE part2 (a int); +ALTER TABLE part ATTACH PARTITION part2 FOR VALUES FROM (101) to (200); +ALTER TABLE part DETACH PARTITION part2; +DROP TABLE part2; + ALTER TABLE part ADD PRIMARY KEY (a); + +ALTER TABLE parent ALTER COLUMN a SET NOT NULL; +ALTER TABLE parent ALTER COLUMN a DROP NOT NULL; +ALTER TABLE parent ALTER COLUMN a SET NOT NULL; + +ALTER TABLE parent ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE parent ALTER COLUMN a SET GENERATED BY DEFAULT; + +ALTER TABLE parent ALTER COLUMN a DROP IDENTITY; + +ALTER TABLE parent ALTER COLUMN a SET STATISTICS 100; + +ALTER TABLE parent ALTER COLUMN a SET STORAGE PLAIN; + +ALTER TABLE parent ENABLE ROW LEVEL SECURITY; +ALTER TABLE parent NO FORCE ROW LEVEL SECURITY; +ALTER TABLE parent FORCE ROW LEVEL SECURITY; +ALTER TABLE parent DISABLE ROW LEVEL SECURITY; + +CREATE STATISTICS parent_stat (dependencies) ON a, c FROM parent; + +ALTER TABLE parent ALTER COLUMN c TYPE numeric; + +ALTER TABLE parent ALTER COLUMN c SET DEFAULT 0; + +CREATE TABLE tbl ( + a int generated always as (b::int * 2) stored, + b text +); + +ALTER TABLE tbl ALTER COLUMN a DROP EXPRESSION; + +ALTER TABLE tbl ALTER COLUMN b SET COMPRESSION pglz; + +CREATE TYPE comptype AS (r float8); +CREATE DOMAIN dcomptype AS comptype; +ALTER DOMAIN dcomptype ADD CONSTRAINT c1 check ((value).r > 0); +ALTER TYPE comptype ALTER ATTRIBUTE r TYPE bigint; diff --git a/src/test/modules/test_ddl_deparse/sql/test_ddl_deparse.sql b/src/test/modules/test_ddl_deparse/sql/test_ddl_deparse.sql index e257a215e4..a4716153df 100644 --- a/src/test/modules/test_ddl_deparse/sql/test_ddl_deparse.sql +++ b/src/test/modules/test_ddl_deparse/sql/test_ddl_deparse.sql @@ -29,9 +29,9 @@ BEGIN -- if alter table, log more IF cmdtype = 'alter table' THEN FOR r2 IN SELECT * - FROM unnest(public.get_altertable_subcmdtypes(r.command)) + FROM public.get_altertable_subcmdinfo(r.command) LOOP - RAISE NOTICE ' subcommand: %', r2.unnest; + RAISE NOTICE ' subcommand: type % desc %', r2.cmdtype, r2.objdesc; END LOOP; END IF; END LOOP; diff --git a/src/test/modules/test_ddl_deparse/test_ddl_deparse--1.0.sql b/src/test/modules/test_ddl_deparse/test_ddl_deparse--1.0.sql index 093005ad80..861d843690 100644 --- a/src/test/modules/test_ddl_deparse/test_ddl_deparse--1.0.sql +++ b/src/test/modules/test_ddl_deparse/test_ddl_deparse--1.0.sql @@ -11,6 +11,8 @@ CREATE FUNCTION get_command_tag(pg_ddl_command) RETURNS text IMMUTABLE STRICT AS 'MODULE_PATHNAME' LANGUAGE C; -CREATE FUNCTION get_altertable_subcmdtypes(pg_ddl_command) - RETURNS text[] IMMUTABLE STRICT +CREATE FUNCTION get_altertable_subcmdinfo(IN cmd pg_ddl_command, + OUT cmdtype text, + OUT objdesc text) + RETURNS SETOF record IMMUTABLE STRICT AS 'MODULE_PATHNAME' LANGUAGE C; 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 9476c3f76e..bdbe05ceeb 100644 --- a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c +++ b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c @@ -11,6 +11,8 @@ #include "postgres.h" #include "catalog/pg_type.h" +#include "funcapi.h" +#include "nodes/execnodes.h" #include "tcop/deparse_utility.h" #include "tcop/utility.h" #include "utils/builtins.h" @@ -19,7 +21,7 @@ PG_MODULE_MAGIC; PG_FUNCTION_INFO_V1(get_command_type); PG_FUNCTION_INFO_V1(get_command_tag); -PG_FUNCTION_INFO_V1(get_altertable_subcmdtypes); +PG_FUNCTION_INFO_V1(get_altertable_subcmdinfo); /* * Return the textual representation of the struct type used to represent a @@ -82,20 +84,30 @@ get_command_tag(PG_FUNCTION_ARGS) * command. */ Datum -get_altertable_subcmdtypes(PG_FUNCTION_ARGS) +get_altertable_subcmdinfo(PG_FUNCTION_ARGS) { CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0); - ArrayBuildState *astate = NULL; ListCell *cell; + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; if (cmd->type != SCT_AlterTable) elog(ERROR, "command is not ALTER TABLE"); + SetSingleFuncCall(fcinfo, 0); + + if (list_length(cmd->d.alterTable.subcmds) == 0) + elog(ERROR, "empty alter table subcommand list"); + foreach(cell, cmd->d.alterTable.subcmds) { CollectedATSubcmd *sub = lfirst(cell); AlterTableCmd *subcmd = castNode(AlterTableCmd, sub->parsetree); - const char *strtype; + const char *strtype = "unrecognized"; + Datum values[2]; + bool nulls[2]; + + memset(values, 0, sizeof(values)); + memset(nulls, 0, sizeof(nulls)); switch (subcmd->subtype) { @@ -120,6 +132,9 @@ get_altertable_subcmdtypes(PG_FUNCTION_ARGS) case AT_SetNotNull: strtype = "SET NOT NULL"; break; + case AT_DropExpression: + strtype = "DROP EXPRESSION"; + break; case AT_CheckNotNull: strtype = "CHECK NOT NULL"; break; @@ -135,6 +150,9 @@ get_altertable_subcmdtypes(PG_FUNCTION_ARGS) case AT_SetStorage: strtype = "SET STORAGE"; break; + case AT_SetCompression: + strtype = "SET COMPRESSION"; + break; case AT_DropColumn: strtype = "DROP COLUMN"; break; @@ -156,6 +174,9 @@ get_altertable_subcmdtypes(PG_FUNCTION_ARGS) case AT_ReAddConstraint: strtype = "(re) ADD CONSTRAINT"; break; + case AT_ReAddDomainConstraint: + strtype = "(re) ADD DOMAIN CONSTRAINT"; + break; case AT_AlterConstraint: strtype = "ALTER CONSTRAINT"; break; @@ -201,6 +222,9 @@ get_altertable_subcmdtypes(PG_FUNCTION_ARGS) case AT_DropOids: strtype = "DROP OIDS"; break; + case AT_SetAccessMethod: + strtype = "SET ACCESS METHOD"; + break; case AT_SetTableSpace: strtype = "SET TABLESPACE"; break; @@ -279,18 +303,41 @@ get_altertable_subcmdtypes(PG_FUNCTION_ARGS) case AT_GenericOptions: strtype = "SET OPTIONS"; break; - default: - strtype = "unrecognized"; + case AT_DetachPartition: + strtype = "DETACH PARTITION"; + break; + case AT_AttachPartition: + strtype = "ATTACH PARTITION"; + break; + case AT_DetachPartitionFinalize: + strtype = "DETACH PARTITION ... FINALIZE"; + break; + case AT_AddIdentity: + strtype = "ADD IDENTITY"; + break; + case AT_SetIdentity: + strtype = "SET IDENTITY"; + break; + case AT_DropIdentity: + strtype = "DROP IDENTITY"; + break; + case AT_ReAddStatistics: + strtype = "(re) ADD STATS"; break; } - astate = - accumArrayResult(astate, CStringGetTextDatum(strtype), - false, TEXTOID, CurrentMemoryContext); + values[0] = CStringGetTextDatum(strtype); + if (OidIsValid(sub->address.objectId)) + { + char *objdesc; + objdesc = getObjectDescription((const ObjectAddress *) &sub->address, false); + values[1] = CStringGetTextDatum(objdesc); + } + else + nulls[1] = true; + + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); } - if (astate == NULL) - elog(ERROR, "empty alter table subcommand list"); - - PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext)); + return (Datum) 0; } -- 2.36.1
signature.asc
Description: PGP signature