From c4b630ac757919105656864bf23b2900a64df2ee Mon Sep 17 00:00:00 2001 From: Vignesh C Date: Tue, 11 Jun 2024 22:26:57 +0530 Subject: [PATCH v20240625 2/3] Introduce "ALL SEQUENCES" support for PostgreSQL logical replication This commit enhances logical replication by enabling the inclusion of all sequences in publications. This improvement facilitates seamless synchronization of sequence data during operations such as CREATE SUBSCRIPTION, REFRESH PUBLICATION, and REFRESH PUBLICATION SEQUENCES. Additionally, a new system view, pg_publication_sequences, has been introduced to list all sequences added to a publication. Furthermore, enhancements to psql commands (\d and \dRp) now allow for better display of publications containing specific sequences or sequences included in a publication. --- doc/src/sgml/ref/create_publication.sgml | 23 +- doc/src/sgml/system-views.sgml | 67 ++++ src/backend/catalog/pg_publication.c | 86 ++++- src/backend/catalog/system_views.sql | 10 + src/backend/commands/publicationcmds.c | 54 ++- src/backend/parser/gram.y | 22 +- src/bin/pg_dump/pg_dump.c | 21 +- src/bin/pg_dump/pg_dump.h | 1 + src/bin/pg_dump/t/002_pg_dump.pl | 11 + src/bin/psql/describe.c | 218 ++++++++--- src/bin/psql/tab-complete.c | 4 +- src/include/catalog/pg_proc.dat | 5 + src/include/catalog/pg_publication.h | 9 + src/include/nodes/parsenodes.h | 6 +- src/test/regress/expected/psql.out | 6 +- src/test/regress/expected/publication.out | 449 ++++++++++++---------- src/test/regress/expected/rules.out | 8 + src/test/regress/sql/publication.sql | 15 + 18 files changed, 712 insertions(+), 303 deletions(-) diff --git a/doc/src/sgml/ref/create_publication.sgml b/doc/src/sgml/ref/create_publication.sgml index fd9c5deac9..107ce63b2b 100644 --- a/doc/src/sgml/ref/create_publication.sgml +++ b/doc/src/sgml/ref/create_publication.sgml @@ -22,10 +22,15 @@ PostgreSQL documentation CREATE PUBLICATION name - [ FOR ALL TABLES + [ FOR ALL object_type [, ...] | FOR publication_object [, ... ] ] [ WITH ( publication_parameter [= value] [, ... ] ) ] +where object type is one of: + + TABLES + SEQUENCES + where publication_object is one of: TABLE [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] [, ... ] @@ -119,10 +124,11 @@ CREATE PUBLICATION name FOR ALL TABLES + FOR ALL SEQUENCES - Marks the publication as one that replicates changes for all tables in - the database, including tables created in the future. + Marks the publication as one that replicates changes for all tables or + sequences in the database, including tables created in the future. @@ -240,10 +246,10 @@ CREATE PUBLICATION name Notes - If FOR TABLE, FOR ALL TABLES or - FOR TABLES IN SCHEMA are not specified, then the - publication starts out with an empty set of tables. That is useful if - tables or schemas are to be added later. + If FOR TABLE, FOR ALL TABLES, + FOR ALL SEQUENCES,or FOR TABLES IN SCHEMA + are not specified, then the publication starts out with an empty set of + tables. That is useful if tables or schemas are to be added later. @@ -259,7 +265,8 @@ CREATE PUBLICATION name To add a table to a publication, the invoking user must have ownership - rights on the table. The FOR ALL TABLES and + rights on the table. The FOR ALL TABLES, + FOR ALL SEQUENCES, and FOR TABLES IN SCHEMA clauses require the invoking user to be a superuser. diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml index 8c18bea902..7491d50dc4 100644 --- a/doc/src/sgml/system-views.sgml +++ b/doc/src/sgml/system-views.sgml @@ -126,6 +126,11 @@ prepared transactions + + pg_publication_sequences + publications and information of their associated sequences + + pg_publication_tables publications and information of their associated tables @@ -2138,6 +2143,68 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx + + <structname>pg_publication_sequences</structname> + + + pg_publication_sequences + + + + The view pg_publication_sequences provides + information about the mapping between publications and information of + sequences they contain. + + + + <structname>pg_publication_sequences</structname> Columns + + + + + Column Type + + + Description + + + + + + + + pubname name + (references pg_publication.pubname) + + + Name of publication + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing sequence + + + + + + sequencename name + (references pg_class.relname) + + + Name of sequence + + + + +
+
+ <structname>pg_publication_tables</structname> diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 0602398a54..175caf23d0 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -137,7 +137,8 @@ static bool is_publishable_class(Oid relid, Form_pg_class reltuple) { return (reltuple->relkind == RELKIND_RELATION || - reltuple->relkind == RELKIND_PARTITIONED_TABLE) && + reltuple->relkind == RELKIND_PARTITIONED_TABLE || + reltuple->relkind == RELKIND_SEQUENCE) && !IsCatalogRelationOid(relid) && reltuple->relpersistence == RELPERSISTENCE_PERMANENT && relid >= FirstNormalObjectId; @@ -997,6 +998,42 @@ GetAllSchemaPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt) return result; } +/* + * Gets list of all relation published by FOR ALL SEQUENCES publication(s). + */ +List * +GetAllSequencesPublicationRelations(void) +{ + Relation classRel; + ScanKeyData key[1]; + TableScanDesc scan; + HeapTuple tuple; + List *result = NIL; + + classRel = table_open(RelationRelationId, AccessShareLock); + + ScanKeyInit(&key[0], + Anum_pg_class_relkind, + BTEqualStrategyNumber, F_CHAREQ, + CharGetDatum(RELKIND_SEQUENCE)); + + scan = table_beginscan_catalog(classRel, 1, key); + + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple); + Oid relid = relForm->oid; + + if (is_publishable_class(relid, relForm)) + result = lappend_oid(result, relid); + } + + table_endscan(scan); + + table_close(classRel, AccessShareLock); + return result; +} + /* * Get publication using oid * @@ -1019,6 +1056,7 @@ GetPublication(Oid pubid) pub->oid = pubid; pub->name = pstrdup(NameStr(pubform->pubname)); pub->alltables = pubform->puballtables; + pub->allsequences = pubform->puballsequences; pub->pubactions.pubinsert = pubform->pubinsert; pub->pubactions.pubupdate = pubform->pubupdate; pub->pubactions.pubdelete = pubform->pubdelete; @@ -1254,3 +1292,49 @@ pg_get_publication_tables(PG_FUNCTION_ARGS) SRF_RETURN_DONE(funcctx); } + +/* + * Returns Oids of sequences in a publication. + */ +Datum +pg_get_publication_sequences(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + char *pubname = text_to_cstring(PG_GETARG_TEXT_PP(0)); + Publication *publication; + List *sequences; + + /* stuff done only on the first call of the function */ + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + + /* create a function context for cross-call persistence */ + funcctx = SRF_FIRSTCALL_INIT(); + + /* switch to memory context appropriate for multiple function calls */ + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + publication = GetPublicationByName(pubname, false); + + if (publication->allsequences) + sequences = GetAllSequencesPublicationRelations(); + + funcctx->user_fctx = (void *) sequences; + + MemoryContextSwitchTo(oldcontext); + } + + /* stuff done on every call of the function */ + funcctx = SRF_PERCALL_SETUP(); + sequences = (List *) funcctx->user_fctx; + + if (funcctx->call_cntr < list_length(sequences)) + { + Oid relid = list_nth_oid(sequences, funcctx->call_cntr); + + SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(relid)); + } + + SRF_RETURN_DONE(funcctx); +} diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index efb29adeb3..1057946dc0 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -398,6 +398,16 @@ CREATE VIEW pg_publication_tables AS pg_class C JOIN pg_namespace N ON (N.oid = C.relnamespace) WHERE C.oid = GPT.relid; +CREATE VIEW pg_publication_sequences AS + SELECT + P.pubname AS pubname, + N.nspname AS schemaname, + C.relname AS sequencename + FROM pg_publication P, + LATERAL pg_get_publication_sequences(P.pubname) GPS, + pg_class C JOIN pg_namespace N ON (N.oid = C.relnamespace) + WHERE C.oid = GPS.relid; + CREATE VIEW pg_locks AS SELECT * FROM pg_lock_status() AS L; diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 6ea709988e..475256f9e4 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -727,6 +727,7 @@ CheckPubRelationColumnList(char *pubname, List *tables, ObjectAddress CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) { + ListCell *lc; Relation rel; ObjectAddress myself; Oid puboid; @@ -741,6 +742,23 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) List *relations = NIL; List *schemaidlist = NIL; + bool for_all_tables = false; + bool for_all_sequences = false; + + /* + * Translate the list of object types (represented by strings) to bool + * flags. + */ + foreach(lc, stmt->for_all_objects) + { + char *val = strVal(lfirst(lc)); + + if (strcmp(val, "tables") == 0) + for_all_tables = true; + else if (strcmp(val, "sequences") == 0) + for_all_sequences = true; + } + /* must have CREATE privilege on database */ aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) @@ -748,11 +766,17 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) get_database_name(MyDatabaseId)); /* FOR ALL TABLES requires superuser */ - if (stmt->for_all_tables && !superuser()) + if (for_all_tables && !superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to create FOR ALL TABLES publication"))); + /* FOR ALL SEQUENCES requires superuser */ + if (for_all_sequences && !superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to create FOR ALL SEQUENCES publication"))); + rel = table_open(PublicationRelationId, RowExclusiveLock); /* Check if name is used */ @@ -782,7 +806,9 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) Anum_pg_publication_oid); values[Anum_pg_publication_oid - 1] = ObjectIdGetDatum(puboid); values[Anum_pg_publication_puballtables - 1] = - BoolGetDatum(stmt->for_all_tables); + BoolGetDatum(for_all_tables); + values[Anum_pg_publication_puballsequences - 1] = + BoolGetDatum(for_all_sequences); values[Anum_pg_publication_pubinsert - 1] = BoolGetDatum(pubactions.pubinsert); values[Anum_pg_publication_pubupdate - 1] = @@ -808,12 +834,17 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) CommandCounterIncrement(); /* Associate objects with the publication. */ - if (stmt->for_all_tables) + if (for_all_tables || for_all_sequences) { /* Invalidate relcache so that publication info is rebuilt. */ CacheInvalidateRelcacheAll(); } - else + + /* + * If the publication might have either tables or sequences (directly or + * through a schema), process that. + */ + if (!for_all_tables || !for_all_sequences) { ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations, &schemaidlist); @@ -1008,7 +1039,7 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, pubform = (Form_pg_publication) GETSTRUCT(tup); /* Invalidate the relcache. */ - if (pubform->puballtables) + if (pubform->puballtables || pubform->puballsequences) { CacheInvalidateRelcacheAll(); } @@ -1494,7 +1525,7 @@ RemovePublicationById(Oid pubid) pubform = (Form_pg_publication) GETSTRUCT(tup); /* Invalidate relcache so that publication info is rebuilt. */ - if (pubform->puballtables) + if (pubform->puballtables || pubform->puballsequences) CacheInvalidateRelcacheAll(); CatalogTupleDelete(rel, &tup->t_self); @@ -1749,7 +1780,7 @@ PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, { ListCell *lc; - Assert(!stmt || !stmt->for_all_tables); + Assert(!stmt || !stmt->for_all_objects); foreach(lc, rels) { @@ -1828,7 +1859,7 @@ PublicationAddSchemas(Oid pubid, List *schemas, bool if_not_exists, { ListCell *lc; - Assert(!stmt || !stmt->for_all_tables); + Assert(!stmt || !stmt->for_all_objects); foreach(lc, schemas) { @@ -1919,6 +1950,13 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) NameStr(form->pubname)), errhint("The owner of a FOR ALL TABLES publication must be a superuser."))); + if (form->puballsequences && !superuser_arg(newOwnerId)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied to change owner of publication \"%s\"", + NameStr(form->pubname)), + errhint("The owner of a FOR ALL SEQUENCES publication must be a superuser."))); + if (!superuser_arg(newOwnerId) && is_schema_publication(form->oid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 4d582950b7..d99285dfa3 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -455,7 +455,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); transform_element_list transform_type_list TriggerTransitions TriggerReferencing vacuum_relation_list opt_vacuum_relation_list - drop_option_list pub_obj_list + drop_option_list pub_obj_list pub_obj_type_list %type opt_routine_body %type group_clause @@ -590,6 +590,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type var_value zone_value %type auth_ident RoleSpec opt_granted_by %type PublicationObjSpec +%type pub_obj_type %type unreserved_keyword type_func_name_keyword %type col_name_keyword reserved_keyword @@ -10557,6 +10558,8 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec * * CREATE PUBLICATION FOR ALL TABLES [WITH options] * + * CREATE PUBLICATION FOR ALL SEQUENCES [WITH options] + * * CREATE PUBLICATION FOR pub_obj [, ...] [WITH options] * * pub_obj is one of: @@ -10575,13 +10578,13 @@ CreatePublicationStmt: n->options = $4; $$ = (Node *) n; } - | CREATE PUBLICATION name FOR ALL TABLES opt_definition + | CREATE PUBLICATION name FOR ALL pub_obj_type_list opt_definition { CreatePublicationStmt *n = makeNode(CreatePublicationStmt); n->pubname = $3; n->options = $7; - n->for_all_tables = true; + n->for_all_objects = $6; $$ = (Node *) n; } | CREATE PUBLICATION name FOR pub_obj_list opt_definition @@ -10693,6 +10696,19 @@ pub_obj_list: PublicationObjSpec { $$ = lappend($1, $3); } ; +pub_obj_type: TABLES + { $$ = (Node *) makeString("tables"); } + | SEQUENCES + { $$ = (Node *) makeString("sequences"); } + ; + +pub_obj_type_list: pub_obj_type + { $$ = list_make1($1); } + | pub_obj_type_list ',' pub_obj_type + { $$ = lappend($1, $3); } + ; + + /***************************************************************************** * * ALTER PUBLICATION name SET ( options ) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index e324070828..953b9128ad 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -4185,6 +4185,7 @@ getPublications(Archive *fout, int *numPublications) int i_pubname; int i_pubowner; int i_puballtables; + int i_puballsequences; int i_pubinsert; int i_pubupdate; int i_pubdelete; @@ -4204,23 +4205,29 @@ getPublications(Archive *fout, int *numPublications) resetPQExpBuffer(query); /* Get the publications. */ - if (fout->remoteVersion >= 130000) + if (fout->remoteVersion >= 170000) appendPQExpBufferStr(query, "SELECT p.tableoid, p.oid, p.pubname, " "p.pubowner, " - "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot " + "p.puballtables, p.puballsequences, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot " + "FROM pg_publication p"); + else if (fout->remoteVersion >= 130000) + appendPQExpBufferStr(query, + "SELECT p.tableoid, p.oid, p.pubname, " + "p.pubowner, " + "p.puballtables, false as p.puballsequences, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot " "FROM pg_publication p"); else if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, "SELECT p.tableoid, p.oid, p.pubname, " "p.pubowner, " - "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot " + "p.puballtables, false as p.puballsequences, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot " "FROM pg_publication p"); else appendPQExpBufferStr(query, "SELECT p.tableoid, p.oid, p.pubname, " "p.pubowner, " - "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot " + "p.puballtables, false as p.puballsequences, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot " "FROM pg_publication p"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -4232,6 +4239,7 @@ getPublications(Archive *fout, int *numPublications) i_pubname = PQfnumber(res, "pubname"); i_pubowner = PQfnumber(res, "pubowner"); i_puballtables = PQfnumber(res, "puballtables"); + i_puballsequences = PQfnumber(res, "puballsequences"); i_pubinsert = PQfnumber(res, "pubinsert"); i_pubupdate = PQfnumber(res, "pubupdate"); i_pubdelete = PQfnumber(res, "pubdelete"); @@ -4251,6 +4259,8 @@ getPublications(Archive *fout, int *numPublications) pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner)); pubinfo[i].puballtables = (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0); + pubinfo[i].puballsequences = + (strcmp(PQgetvalue(res, i, i_puballsequences), "t") == 0); pubinfo[i].pubinsert = (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0); pubinfo[i].pubupdate = @@ -4304,6 +4314,9 @@ dumpPublication(Archive *fout, const PublicationInfo *pubinfo) if (pubinfo->puballtables) appendPQExpBufferStr(query, " FOR ALL TABLES"); + if (pubinfo->puballsequences) + appendPQExpBufferStr(query, " FOR ALL SEQUENCES"); + appendPQExpBufferStr(query, " WITH (publish = '"); if (pubinfo->pubinsert) { diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 865823868f..976115ab3d 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -619,6 +619,7 @@ typedef struct _PublicationInfo DumpableObject dobj; const char *rolname; bool puballtables; + bool puballsequences; bool pubinsert; bool pubupdate; bool pubdelete; diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index d3dd8784d6..ace1d1b661 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -2950,6 +2950,17 @@ my %tests = ( like => { %full_runs, section_post_data => 1, }, }, + 'CREATE PUBLICATION pub5' => { + create_order => 50, + create_sql => 'CREATE PUBLICATION pub5 + FOR ALL SEQUENCES + WITH (publish = \'\');', + regexp => qr/^ + \QCREATE PUBLICATION pub5 FOR ALL SEQUENCES WITH (publish = '');\E + /xm, + like => { %full_runs, section_post_data => 1, }, + }, + 'CREATE SUBSCRIPTION sub1' => { create_order => 50, create_sql => 'CREATE SUBSCRIPTION sub1 diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index f67bf0b892..482c756b3a 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -1715,28 +1715,19 @@ describeOneTableDetails(const char *schemaname, if (tableinfo.relkind == RELKIND_SEQUENCE) { PGresult *result = NULL; - printQueryOpt myopt = pset.popt; - char *footers[2] = {NULL, NULL}; if (pset.sversion >= 100000) { printfPQExpBuffer(&buf, - "SELECT pg_catalog.format_type(seqtypid, NULL) AS \"%s\",\n" - " seqstart AS \"%s\",\n" - " seqmin AS \"%s\",\n" - " seqmax AS \"%s\",\n" - " seqincrement AS \"%s\",\n" - " CASE WHEN seqcycle THEN '%s' ELSE '%s' END AS \"%s\",\n" - " seqcache AS \"%s\"\n", - gettext_noop("Type"), - gettext_noop("Start"), - gettext_noop("Minimum"), - gettext_noop("Maximum"), - gettext_noop("Increment"), + "SELECT pg_catalog.format_type(seqtypid, NULL),\n" + " seqstart,\n" + " seqmin,\n" + " seqmax,\n" + " seqincrement,\n" + " CASE WHEN seqcycle THEN '%s' ELSE '%s' END,\n" + " seqcache\n", gettext_noop("yes"), - gettext_noop("no"), - gettext_noop("Cycles?"), - gettext_noop("Cache")); + gettext_noop("no")); appendPQExpBuffer(&buf, "FROM pg_catalog.pg_sequence\n" "WHERE seqrelid = '%s';", @@ -1745,22 +1736,15 @@ describeOneTableDetails(const char *schemaname, else { printfPQExpBuffer(&buf, - "SELECT 'bigint' AS \"%s\",\n" - " start_value AS \"%s\",\n" - " min_value AS \"%s\",\n" - " max_value AS \"%s\",\n" - " increment_by AS \"%s\",\n" - " CASE WHEN is_cycled THEN '%s' ELSE '%s' END AS \"%s\",\n" - " cache_value AS \"%s\"\n", - gettext_noop("Type"), - gettext_noop("Start"), - gettext_noop("Minimum"), - gettext_noop("Maximum"), - gettext_noop("Increment"), + "SELECT 'bigint',\n" + " start_value,\n" + " min_value,\n" + " max_value,\n" + " increment_by,\n" + " CASE WHEN is_cycled THEN '%s' ELSE '%s' END,\n" + " cache_value\n", gettext_noop("yes"), - gettext_noop("no"), - gettext_noop("Cycles?"), - gettext_noop("Cache")); + gettext_noop("no")); appendPQExpBuffer(&buf, "FROM %s", fmtId(schemaname)); /* must be separate because fmtId isn't reentrant */ appendPQExpBuffer(&buf, ".%s;", fmtId(relationname)); @@ -1770,6 +1754,59 @@ describeOneTableDetails(const char *schemaname, if (!res) goto error_return; + numrows = PQntuples(res); + + /* + * XXX reset to use expanded output for sequences (maybe we should + * keep this disabled, just like for tables?) + */ + myopt.expanded = pset.popt.topt.expanded; + + printTableInit(&cont, &myopt, title.data, 7, numrows); + printTableInitialized = true; + + if (tableinfo.relpersistence == 'u') + printfPQExpBuffer(&title, _("Unlogged sequence \"%s.%s\""), + schemaname, relationname); + else + printfPQExpBuffer(&title, _("Sequence \"%s.%s\""), + schemaname, relationname); + + printTableAddHeader(&cont, gettext_noop("Type"), true, 'l'); + printTableAddHeader(&cont, gettext_noop("Start"), true, 'r'); + printTableAddHeader(&cont, gettext_noop("Minimum"), true, 'r'); + printTableAddHeader(&cont, gettext_noop("Maximum"), true, 'r'); + printTableAddHeader(&cont, gettext_noop("Increment"), true, 'r'); + printTableAddHeader(&cont, gettext_noop("Cycles?"), true, 'l'); + printTableAddHeader(&cont, gettext_noop("Cache"), true, 'r'); + + /* Generate table cells to be printed */ + for (i = 0; i < numrows; i++) + { + /* Type */ + printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false); + + /* Start */ + printTableAddCell(&cont, PQgetvalue(res, i, 1), false, false); + + /* Minimum */ + printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false); + + /* Maximum */ + printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false); + + /* Increment */ + printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false); + + /* Cycles? */ + printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false); + + /* Cache */ + printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false); + } + + /* Footer information about a sequence */ + /* Get the column that owns this sequence */ printfPQExpBuffer(&buf, "SELECT pg_catalog.quote_ident(nspname) || '.' ||" "\n pg_catalog.quote_ident(relname) || '.' ||" @@ -1801,32 +1838,52 @@ describeOneTableDetails(const char *schemaname, switch (PQgetvalue(result, 0, 1)[0]) { case 'a': - footers[0] = psprintf(_("Owned by: %s"), - PQgetvalue(result, 0, 0)); + printTableAddFooter(&cont, + psprintf(_("Owned by: %s"), + PQgetvalue(result, 0, 0))); break; case 'i': - footers[0] = psprintf(_("Sequence for identity column: %s"), - PQgetvalue(result, 0, 0)); + printTableAddFooter(&cont, + psprintf(_("Sequence for identity column: %s"), + PQgetvalue(result, 0, 0))); break; } } PQclear(result); - if (tableinfo.relpersistence == 'u') - printfPQExpBuffer(&title, _("Unlogged sequence \"%s.%s\""), - schemaname, relationname); - else - printfPQExpBuffer(&title, _("Sequence \"%s.%s\""), - schemaname, relationname); + /* print any publications */ + if (pset.sversion >= 170000) + { + int tuples = 0; - myopt.footers = footers; - myopt.topt.default_footer = false; - myopt.title = title.data; - myopt.translate_header = true; + printfPQExpBuffer(&buf, + "SELECT pubname\n" + "FROM pg_catalog.pg_publication p\n" + "WHERE p.puballsequences AND pg_catalog.pg_relation_is_publishable('%s')\n" + "ORDER BY 1;", + oid); - printQuery(res, &myopt, pset.queryFout, false, pset.logfile); + result = PSQLexec(buf.data); + if (!result) + goto error_return; + else + tuples = PQntuples(result); + + if (tuples > 0) + printTableAddFooter(&cont, _("Publications:")); + + /* Might be an empty set - that's ok */ + for (i = 0; i < tuples; i++) + { + printfPQExpBuffer(&buf, " \"%s\"", + PQgetvalue(result, i, 0)); + + printTableAddFooter(&cont, buf.data); + } + PQclear(result); + } - free(footers[0]); + printTable(&cont, pset.queryFout, false, pset.logfile); retval = true; goto error_return; /* not an error, just return early */ @@ -2053,6 +2110,11 @@ describeOneTableDetails(const char *schemaname, for (i = 0; i < cols; i++) printTableAddHeader(&cont, headers[i], true, 'l'); + res = PSQLexec(buf.data); + if (!res) + goto error_return; + numrows = PQntuples(res); + /* Generate table cells to be printed */ for (i = 0; i < numrows; i++) { @@ -6219,7 +6281,7 @@ listPublications(const char *pattern) PQExpBufferData buf; PGresult *res; printQueryOpt myopt = pset.popt; - static const bool translate_columns[] = {false, false, false, false, false, false, false, false}; + static const bool translate_columns[] = {false, false, false, false, false, false, false, false, false}; if (pset.sversion < 100000) { @@ -6233,19 +6295,37 @@ listPublications(const char *pattern) initPQExpBuffer(&buf); - printfPQExpBuffer(&buf, - "SELECT pubname AS \"%s\",\n" - " pg_catalog.pg_get_userbyid(pubowner) AS \"%s\",\n" - " puballtables AS \"%s\",\n" - " pubinsert AS \"%s\",\n" - " pubupdate AS \"%s\",\n" - " pubdelete AS \"%s\"", - gettext_noop("Name"), - gettext_noop("Owner"), - gettext_noop("All tables"), - gettext_noop("Inserts"), - gettext_noop("Updates"), - gettext_noop("Deletes")); + if (pset.sversion >= 170000) + printfPQExpBuffer(&buf, + "SELECT pubname AS \"%s\",\n" + " pg_catalog.pg_get_userbyid(pubowner) AS \"%s\",\n" + " puballtables AS \"%s\",\n" + " puballsequences AS \"%s\",\n" + " pubinsert AS \"%s\",\n" + " pubupdate AS \"%s\",\n" + " pubdelete AS \"%s\"", + gettext_noop("Name"), + gettext_noop("Owner"), + gettext_noop("All tables"), + gettext_noop("All sequences"), + gettext_noop("Inserts"), + gettext_noop("Updates"), + gettext_noop("Deletes")); + else + printfPQExpBuffer(&buf, + "SELECT pubname AS \"%s\",\n" + " pg_catalog.pg_get_userbyid(pubowner) AS \"%s\",\n" + " puballtables AS \"%s\",\n" + " pubinsert AS \"%s\",\n" + " pubupdate AS \"%s\",\n" + " pubdelete AS \"%s\"", + gettext_noop("Name"), + gettext_noop("Owner"), + gettext_noop("All tables"), + gettext_noop("Inserts"), + gettext_noop("Updates"), + gettext_noop("Deletes")); + if (pset.sversion >= 110000) appendPQExpBuffer(&buf, ",\n pubtruncate AS \"%s\"", @@ -6343,6 +6423,7 @@ describePublications(const char *pattern) PGresult *res; bool has_pubtruncate; bool has_pubviaroot; + bool has_pubsequence; PQExpBufferData title; printTableContent cont; @@ -6359,6 +6440,7 @@ describePublications(const char *pattern) has_pubtruncate = (pset.sversion >= 110000); has_pubviaroot = (pset.sversion >= 130000); + has_pubsequence = (pset.sversion >= 170000); initPQExpBuffer(&buf); @@ -6372,6 +6454,10 @@ describePublications(const char *pattern) if (has_pubviaroot) appendPQExpBufferStr(&buf, ", pubviaroot"); + if (has_pubsequence) + appendPQExpBufferStr(&buf, + ", puballsequences"); + appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_publication\n"); @@ -6423,6 +6509,8 @@ describePublications(const char *pattern) ncols++; if (has_pubviaroot) ncols++; + if (has_pubsequence) + ncols ++; initPQExpBuffer(&title); printfPQExpBuffer(&title, _("Publication %s"), pubname); @@ -6430,6 +6518,8 @@ describePublications(const char *pattern) printTableAddHeader(&cont, gettext_noop("Owner"), true, align); printTableAddHeader(&cont, gettext_noop("All tables"), true, align); + if (has_pubsequence) + printTableAddHeader(&cont, gettext_noop("All sequences"), true, align); printTableAddHeader(&cont, gettext_noop("Inserts"), true, align); printTableAddHeader(&cont, gettext_noop("Updates"), true, align); printTableAddHeader(&cont, gettext_noop("Deletes"), true, align); @@ -6440,6 +6530,10 @@ describePublications(const char *pattern) printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false); printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false); + + if (has_pubsequence) + printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false); /* all sequences */ + printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false); printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false); printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index d453e224d9..f1ee348909 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3159,9 +3159,9 @@ psql_completion(const char *text, int start, int end) /* CREATE PUBLICATION */ else if (Matches("CREATE", "PUBLICATION", MatchAny)) - COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "FOR TABLES IN SCHEMA", "WITH ("); + COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "FOR ALL SEQUENCES", "FOR TABLES IN SCHEMA", "WITH ("); else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR")) - COMPLETE_WITH("TABLE", "ALL TABLES", "TABLES IN SCHEMA"); + COMPLETE_WITH("TABLE", "ALL TABLES", "ALL SEQUENCES", "TABLES IN SCHEMA"); else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL")) COMPLETE_WITH("TABLES"); else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES")) diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 990ef2f836..8e68adb01f 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11945,6 +11945,11 @@ proargmodes => '{v,o,o,o,o}', proargnames => '{pubname,pubid,relid,attrs,qual}', prosrc => 'pg_get_publication_tables' }, +{ oid => '8000', descr => 'get OIDs of sequences in a publication', + proname => 'pg_get_publication_sequences', prorows => '1000', proretset => 't', + provolatile => 's', prorettype => 'oid', proargtypes => 'text', + proallargtypes => '{text,oid}', proargmodes => '{i,o}', + proargnames => '{pubname,relid}', prosrc => 'pg_get_publication_sequences' }, { oid => '6121', descr => 'returns whether a relation can be part of a publication', proname => 'pg_relation_is_publishable', provolatile => 's', diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h index 2f1b6abbfa..8cc0fe9d0d 100644 --- a/src/include/catalog/pg_publication.h +++ b/src/include/catalog/pg_publication.h @@ -40,6 +40,12 @@ CATALOG(pg_publication,6104,PublicationRelationId) */ bool puballtables; + /* + * indicates that this is special publication which should encompass all + * sequences in the database (except for the unlogged and temp ones) + */ + bool puballsequences; + /* true if inserts are published */ bool pubinsert; @@ -102,6 +108,7 @@ typedef struct Publication Oid oid; char *name; bool alltables; + bool allsequences; bool pubviaroot; PublicationActions pubactions; } Publication; @@ -148,6 +155,8 @@ extern List *GetPubPartitionOptionRelations(List *result, extern Oid GetTopMostAncestorInPublication(Oid puboid, List *ancestors, int *ancestor_level); +extern List *GetAllSequencesPublicationRelations(void); + extern bool is_publishable_relation(Relation rel); extern bool is_schema_publication(Oid pubid); extern ObjectAddress publication_add_relation(Oid pubid, PublicationRelInfo *pri, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 85a62b538e..62d1cf47e2 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -4168,7 +4168,8 @@ typedef struct CreatePublicationStmt char *pubname; /* Name of the publication */ List *options; /* List of DefElem nodes */ List *pubobjects; /* Optional list of publication objects */ - bool for_all_tables; /* Special publication for all tables in db */ + List *for_all_objects; /* Special publication for all objects in + * db */ } CreatePublicationStmt; typedef enum AlterPublicationAction @@ -4191,7 +4192,8 @@ typedef struct AlterPublicationStmt * objects. */ List *pubobjects; /* Optional list of publication objects */ - bool for_all_tables; /* Special publication for all tables in db */ + List *for_all_objects; /* Special publication for all objects in + * db */ AlterPublicationAction action; /* What action to perform with the given * objects */ } AlterPublicationStmt; diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 3bbe4c5f97..2581b4934b 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -6248,9 +6248,9 @@ List of schemas (0 rows) \dRp "no.such.publication" - List of publications - Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root -------+-------+------------+---------+---------+---------+-----------+---------- + List of publications + Name | Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +------+-------+------------+---------------+---------+---------+---------+-----------+---------- (0 rows) \dRs "no.such.subscription" diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out index 30b6371134..d54008ae6f 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -30,20 +30,20 @@ ERROR: conflicting or redundant options LINE 1: ...ub_xxx WITH (publish_via_partition_root = 'true', publish_vi... ^ \dRp - List of publications - Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------+--------------------------+------------+---------+---------+---------+-----------+---------- - testpib_ins_trunct | regress_publication_user | f | t | f | f | f | f - testpub_default | regress_publication_user | f | f | t | f | f | f + List of publications + Name | Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------+--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + testpib_ins_trunct | regress_publication_user | f | f | t | f | f | f | f + testpub_default | regress_publication_user | f | f | f | t | f | f | f (2 rows) ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete'); \dRp - List of publications - Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------+--------------------------+------------+---------+---------+---------+-----------+---------- - testpib_ins_trunct | regress_publication_user | f | t | f | f | f | f - testpub_default | regress_publication_user | f | t | t | t | f | f + List of publications + Name | Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------+--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + testpib_ins_trunct | regress_publication_user | f | f | t | f | f | f | f + testpub_default | regress_publication_user | f | f | t | t | t | f | f (2 rows) --- adding tables @@ -87,10 +87,10 @@ RESET client_min_messages; -- should be able to add schema to 'FOR TABLE' publication ALTER PUBLICATION testpub_fortable ADD TABLES IN SCHEMA pub_test; \dRp+ testpub_fortable - Publication testpub_fortable - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_fortable + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "public.testpub_tbl1" Tables from schemas: @@ -99,20 +99,20 @@ Tables from schemas: -- should be able to drop schema from 'FOR TABLE' publication ALTER PUBLICATION testpub_fortable DROP TABLES IN SCHEMA pub_test; \dRp+ testpub_fortable - Publication testpub_fortable - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_fortable + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "public.testpub_tbl1" -- should be able to set schema to 'FOR TABLE' publication ALTER PUBLICATION testpub_fortable SET TABLES IN SCHEMA pub_test; \dRp+ testpub_fortable - Publication testpub_fortable - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_fortable + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test" @@ -123,10 +123,10 @@ CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pub_test; CREATE PUBLICATION testpub_for_tbl_schema FOR TABLES IN SCHEMA pub_test, TABLE pub_test.testpub_nopk; RESET client_min_messages; \dRp+ testpub_for_tbl_schema - Publication testpub_for_tbl_schema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_for_tbl_schema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "pub_test.testpub_nopk" Tables from schemas: @@ -144,10 +144,10 @@ LINE 1: ...CATION testpub_parsertst FOR TABLES IN SCHEMA foo, test.foo; -- should be able to add a table of the same schema to the schema publication ALTER PUBLICATION testpub_forschema ADD TABLE pub_test.testpub_nopk; \dRp+ testpub_forschema - Publication testpub_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "pub_test.testpub_nopk" Tables from schemas: @@ -156,10 +156,10 @@ Tables from schemas: -- should be able to drop the table ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk; \dRp+ testpub_forschema - Publication testpub_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test" @@ -170,10 +170,10 @@ ERROR: relation "testpub_nopk" is not part of the publication -- should be able to set table to schema publication ALTER PUBLICATION testpub_forschema SET TABLE pub_test.testpub_nopk; \dRp+ testpub_forschema - Publication testpub_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "pub_test.testpub_nopk" @@ -195,10 +195,10 @@ Publications: "testpub_foralltables" \dRp+ testpub_foralltables - Publication testpub_foralltables - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | t | t | t | f | f | f + Publication testpub_foralltables + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | t | f | t | t | f | f | f (1 row) DROP TABLE testpub_tbl2; @@ -210,24 +210,53 @@ CREATE PUBLICATION testpub3 FOR TABLE testpub_tbl3; CREATE PUBLICATION testpub4 FOR TABLE ONLY testpub_tbl3; RESET client_min_messages; \dRp+ testpub3 - Publication testpub3 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub3 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "public.testpub_tbl3" "public.testpub_tbl3a" \dRp+ testpub4 - Publication testpub4 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub4 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "public.testpub_tbl3" DROP TABLE testpub_tbl3, testpub_tbl3a; DROP PUBLICATION testpub3, testpub4; +--- adding sequences +CREATE SEQUENCE testpub_seq0; +CREATE SEQUENCE pub_test.testpub_seq1; +SET client_min_messages = 'ERROR'; +CREATE PUBLICATION testpub_forallsequences FOR ALL SEQUENCES; +RESET client_min_messages; +SELECT pubname, puballtables, puballsequences FROM pg_publication WHERE pubname = 'testpub_forallsequences'; + pubname | puballtables | puballsequences +-------------------------+--------------+----------------- + testpub_forallsequences | f | t +(1 row) + +\d+ pub_test.testpub_seq1 + Sequence "pub_test.testpub_seq1" + Type | Start | Minimum | Maximum | Increment | Cycles? | Cache +--------+-------+---------+---------------------+-----------+---------+------- + bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 +Publications: + "testpub_forallsequences" + +\dRp+ testpub_forallsequences + Publication testpub_forallsequences + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | t | f +(1 row) + +DROP SEQUENCE testpub_seq0, pub_test.testpub_seq1; +DROP PUBLICATION testpub_forallsequences; -- Tests for partitioned tables SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_forparted; @@ -243,10 +272,10 @@ UPDATE testpub_parted1 SET a = 1; -- only parent is listed as being in publication, not the partition ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted; \dRp+ testpub_forparted - Publication testpub_forparted - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_forparted + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "public.testpub_parted" @@ -261,10 +290,10 @@ ALTER TABLE testpub_parted DETACH PARTITION testpub_parted1; UPDATE testpub_parted1 SET a = 1; ALTER PUBLICATION testpub_forparted SET (publish_via_partition_root = true); \dRp+ testpub_forparted - Publication testpub_forparted - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | t + Publication testpub_forparted + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | t Tables: "public.testpub_parted" @@ -293,10 +322,10 @@ SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub5 FOR TABLE testpub_rf_tbl1, testpub_rf_tbl2 WHERE (c <> 'test' AND d < 5) WITH (publish = 'insert'); RESET client_min_messages; \dRp+ testpub5 - Publication testpub5 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | f | f | f | f + Publication testpub5 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "public.testpub_rf_tbl2" WHERE ((c <> 'test'::text) AND (d < 5)) @@ -309,10 +338,10 @@ Tables: ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl3 WHERE (e > 1000 AND e < 2000); \dRp+ testpub5 - Publication testpub5 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | f | f | f | f + Publication testpub5 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "public.testpub_rf_tbl2" WHERE ((c <> 'test'::text) AND (d < 5)) @@ -328,10 +357,10 @@ Publications: ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl2; \dRp+ testpub5 - Publication testpub5 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | f | f | f | f + Publication testpub5 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "public.testpub_rf_tbl3" WHERE ((e > 1000) AND (e < 2000)) @@ -339,10 +368,10 @@ Tables: -- remove testpub_rf_tbl1 and add testpub_rf_tbl3 again (another WHERE expression) ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e > 300 AND e < 500); \dRp+ testpub5 - Publication testpub5 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | f | f | f | f + Publication testpub5 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | f | f | f | f Tables: "public.testpub_rf_tbl3" WHERE ((e > 300) AND (e < 500)) @@ -375,10 +404,10 @@ SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_syntax1 FOR TABLE testpub_rf_tbl1, ONLY testpub_rf_tbl3 WHERE (e < 999) WITH (publish = 'insert'); RESET client_min_messages; \dRp+ testpub_syntax1 - Publication testpub_syntax1 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | f | f | f | f + Publication testpub_syntax1 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "public.testpub_rf_tbl3" WHERE (e < 999) @@ -388,10 +417,10 @@ SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_syntax2 FOR TABLE testpub_rf_tbl1, testpub_rf_schema1.testpub_rf_tbl5 WHERE (h < 999) WITH (publish = 'insert'); RESET client_min_messages; \dRp+ testpub_syntax2 - Publication testpub_syntax2 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | f | f | f | f + Publication testpub_syntax2 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "testpub_rf_schema1.testpub_rf_tbl5" WHERE (h < 999) @@ -506,10 +535,10 @@ CREATE PUBLICATION testpub6 FOR TABLES IN SCHEMA testpub_rf_schema2; ALTER PUBLICATION testpub6 SET TABLES IN SCHEMA testpub_rf_schema2, TABLE testpub_rf_schema2.testpub_rf_tbl6 WHERE (i < 99); RESET client_min_messages; \dRp+ testpub6 - Publication testpub6 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub6 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "testpub_rf_schema2.testpub_rf_tbl6" WHERE (i < 99) Tables from schemas: @@ -723,10 +752,10 @@ CREATE PUBLICATION testpub_table_ins WITH (publish = 'insert, truncate'); RESET client_min_messages; ALTER PUBLICATION testpub_table_ins ADD TABLE testpub_tbl5 (a); -- ok \dRp+ testpub_table_ins - Publication testpub_table_ins - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | f | f | t | f + Publication testpub_table_ins + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | f | f | t | f Tables: "public.testpub_tbl5" (a) @@ -910,10 +939,10 @@ CREATE TABLE testpub_tbl_both_filters (a int, b int, c int, PRIMARY KEY (a,c)); ALTER TABLE testpub_tbl_both_filters REPLICA IDENTITY USING INDEX testpub_tbl_both_filters_pkey; ALTER PUBLICATION testpub_both_filters ADD TABLE testpub_tbl_both_filters (a,c) WHERE (c != 1); \dRp+ testpub_both_filters - Publication testpub_both_filters - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_both_filters + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "public.testpub_tbl_both_filters" (a, c) WHERE (c <> 1) @@ -1118,10 +1147,10 @@ ERROR: relation "testpub_tbl1" is already member of publication "testpub_fortbl CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1; ERROR: publication "testpub_fortbl" already exists \dRp+ testpub_fortbl - Publication testpub_fortbl - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_fortbl + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "pub_test.testpub_nopk" "public.testpub_tbl1" @@ -1159,10 +1188,10 @@ Publications: "testpub_fortbl" \dRp+ testpub_default - Publication testpub_default - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | f | f + Publication testpub_default + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | f | f Tables: "pub_test.testpub_nopk" "public.testpub_tbl1" @@ -1240,10 +1269,10 @@ REVOKE CREATE ON DATABASE regression FROM regress_publication_user2; DROP TABLE testpub_parted; DROP TABLE testpub_tbl1; \dRp+ testpub_default - Publication testpub_default - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | f | f + Publication testpub_default + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | f | f (1 row) -- fail - must be owner of publication @@ -1253,20 +1282,20 @@ ERROR: must be owner of publication testpub_default RESET ROLE; ALTER PUBLICATION testpub_default RENAME TO testpub_foo; \dRp testpub_foo - List of publications - Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root --------------+--------------------------+------------+---------+---------+---------+-----------+---------- - testpub_foo | regress_publication_user | f | t | t | t | f | f + List of publications + Name | Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +-------------+--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + testpub_foo | regress_publication_user | f | f | t | t | t | f | f (1 row) -- rename back to keep the rest simple ALTER PUBLICATION testpub_foo RENAME TO testpub_default; ALTER PUBLICATION testpub_default OWNER TO regress_publication_user2; \dRp testpub_default - List of publications - Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ------------------+---------------------------+------------+---------+---------+---------+-----------+---------- - testpub_default | regress_publication_user2 | f | t | t | t | f | f + List of publications + Name | Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +-----------------+---------------------------+------------+---------------+---------+---------+---------+-----------+---------- + testpub_default | regress_publication_user2 | f | f | t | t | t | f | f (1 row) -- adding schemas and tables @@ -1282,19 +1311,19 @@ CREATE TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA"(id int); SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub1_forschema FOR TABLES IN SCHEMA pub_test1; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" CREATE PUBLICATION testpub2_forschema FOR TABLES IN SCHEMA pub_test1, pub_test2, pub_test3; \dRp+ testpub2_forschema - Publication testpub2_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub2_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1308,44 +1337,44 @@ CREATE PUBLICATION testpub6_forschema FOR TABLES IN SCHEMA "CURRENT_SCHEMA", CUR CREATE PUBLICATION testpub_fortable FOR TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA"; RESET client_min_messages; \dRp+ testpub3_forschema - Publication testpub3_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub3_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "public" \dRp+ testpub4_forschema - Publication testpub4_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub4_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "CURRENT_SCHEMA" \dRp+ testpub5_forschema - Publication testpub5_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub5_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "CURRENT_SCHEMA" "public" \dRp+ testpub6_forschema - Publication testpub6_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub6_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "CURRENT_SCHEMA" "public" \dRp+ testpub_fortable - Publication testpub_fortable - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_fortable + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "CURRENT_SCHEMA.CURRENT_SCHEMA" @@ -1379,10 +1408,10 @@ ERROR: schema "testpub_view" does not exist -- dropping the schema should reflect the change in publication DROP SCHEMA pub_test3; \dRp+ testpub2_forschema - Publication testpub2_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub2_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1390,20 +1419,20 @@ Tables from schemas: -- renaming the schema should reflect the change in publication ALTER SCHEMA pub_test1 RENAME to pub_test1_renamed; \dRp+ testpub2_forschema - Publication testpub2_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub2_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1_renamed" "pub_test2" ALTER SCHEMA pub_test1_renamed RENAME to pub_test1; \dRp+ testpub2_forschema - Publication testpub2_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub2_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1411,10 +1440,10 @@ Tables from schemas: -- alter publication add schema ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test2; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1423,10 +1452,10 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA non_existent_schema; ERROR: schema "non_existent_schema" does not exist \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1435,10 +1464,10 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test1; ERROR: schema "pub_test1" is already member of publication "testpub1_forschema" \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1446,10 +1475,10 @@ Tables from schemas: -- alter publication drop schema ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" @@ -1457,10 +1486,10 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2; ERROR: tables from schema "pub_test2" are not part of the publication \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" @@ -1468,29 +1497,29 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA non_existent_schema; ERROR: schema "non_existent_schema" does not exist \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" -- drop all schemas ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f (1 row) -- alter publication set multiple schema ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, pub_test2; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1499,10 +1528,10 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA non_existent_schema; ERROR: schema "non_existent_schema" does not exist \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1511,10 +1540,10 @@ Tables from schemas: -- removing the duplicate schemas ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, pub_test1; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" @@ -1593,18 +1622,18 @@ SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub3_forschema; RESET client_min_messages; \dRp+ testpub3_forschema - Publication testpub3_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub3_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f (1 row) ALTER PUBLICATION testpub3_forschema SET TABLES IN SCHEMA pub_test1; \dRp+ testpub3_forschema - Publication testpub3_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub3_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables from schemas: "pub_test1" @@ -1614,20 +1643,20 @@ CREATE PUBLICATION testpub_forschema_fortable FOR TABLES IN SCHEMA pub_test1, TA CREATE PUBLICATION testpub_fortable_forschema FOR TABLE pub_test2.tbl1, TABLES IN SCHEMA pub_test1; RESET client_min_messages; \dRp+ testpub_forschema_fortable - Publication testpub_forschema_fortable - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_forschema_fortable + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "pub_test2.tbl1" Tables from schemas: "pub_test1" \dRp+ testpub_fortable_forschema - Publication testpub_fortable_forschema - Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ---------------------------+------------+---------+---------+---------+-----------+---------- - regress_publication_user | f | t | t | t | t | f + Publication testpub_fortable_forschema + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | f Tables: "pub_test2.tbl1" Tables from schemas: diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 13178e2b3d..1c646f15a1 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1441,6 +1441,14 @@ pg_prepared_xacts| SELECT p.transaction, FROM ((pg_prepared_xact() p(transaction, gid, prepared, ownerid, dbid) LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid))); +pg_publication_sequences| SELECT p.pubname, + n.nspname AS schemaname, + c.relname AS sequencename + FROM pg_publication p, + LATERAL pg_get_publication_sequences((p.pubname)::text) gps(relid), + (pg_class c + JOIN pg_namespace n ON ((n.oid = c.relnamespace))) + WHERE (c.oid = gps.relid); pg_publication_tables| SELECT p.pubname, n.nspname AS schemaname, c.relname AS tablename, diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql index 479d4f3264..e9fc959c8b 100644 --- a/src/test/regress/sql/publication.sql +++ b/src/test/regress/sql/publication.sql @@ -117,6 +117,21 @@ RESET client_min_messages; DROP TABLE testpub_tbl3, testpub_tbl3a; DROP PUBLICATION testpub3, testpub4; +--- adding sequences +CREATE SEQUENCE testpub_seq0; +CREATE SEQUENCE pub_test.testpub_seq1; + +SET client_min_messages = 'ERROR'; +CREATE PUBLICATION testpub_forallsequences FOR ALL SEQUENCES; +RESET client_min_messages; + +SELECT pubname, puballtables, puballsequences FROM pg_publication WHERE pubname = 'testpub_forallsequences'; +\d+ pub_test.testpub_seq1 +\dRp+ testpub_forallsequences +DROP SEQUENCE testpub_seq0, pub_test.testpub_seq1; +DROP PUBLICATION testpub_forallsequences; + + -- Tests for partitioned tables SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_forparted; -- 2.34.1