diff options
Diffstat (limited to 'src')
43 files changed, 475 insertions, 3813 deletions
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 31c80f7209f..ac6043514f1 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -1941,14 +1941,12 @@ get_object_address_publication_schema(List *object, bool missing_ok) char *pubname; char *schemaname; Oid schemaid; - char *objtype; ObjectAddressSet(address, PublicationNamespaceRelationId, InvalidOid); /* Fetch schema name and publication name from input list */ schemaname = strVal(linitial(object)); pubname = strVal(lsecond(object)); - objtype = strVal(lthird(object)); schemaid = get_namespace_oid(schemaname, missing_ok); if (!OidIsValid(schemaid)) @@ -1961,12 +1959,10 @@ get_object_address_publication_schema(List *object, bool missing_ok) /* Find the publication schema mapping in syscache */ address.objectId = - GetSysCacheOid3(PUBLICATIONNAMESPACEMAP, + GetSysCacheOid2(PUBLICATIONNAMESPACEMAP, Anum_pg_publication_namespace_oid, ObjectIdGetDatum(schemaid), - ObjectIdGetDatum(pub->oid), - CharGetDatum(objtype[0])); - + ObjectIdGetDatum(pub->oid)); if (!OidIsValid(address.objectId) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -2247,6 +2243,7 @@ pg_get_object_address(PG_FUNCTION_ARGS) case OBJECT_DOMCONSTRAINT: case OBJECT_CAST: case OBJECT_USER_MAPPING: + case OBJECT_PUBLICATION_NAMESPACE: case OBJECT_PUBLICATION_REL: case OBJECT_DEFACL: case OBJECT_TRANSFORM: @@ -2271,7 +2268,6 @@ pg_get_object_address(PG_FUNCTION_ARGS) /* fall through to check args length */ /* FALLTHROUGH */ case OBJECT_OPERATOR: - case OBJECT_PUBLICATION_NAMESPACE: if (list_length(args) != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -2343,8 +2339,6 @@ pg_get_object_address(PG_FUNCTION_ARGS) objnode = (Node *) list_make2(name, linitial(args)); break; case OBJECT_PUBLICATION_NAMESPACE: - objnode = (Node *) list_make3(linitial(name), linitial(args), lsecond(args)); - break; case OBJECT_USER_MAPPING: objnode = (Node *) list_make2(linitial(name), linitial(args)); break; @@ -2900,12 +2894,11 @@ get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId) * * Get publication name and schema name from the object address into pubname and * nspname. Both pubname and nspname are palloc'd strings which will be freed by - * the caller. The last parameter specifies which object type is included from - * the schema. + * the caller. */ static bool getPublicationSchemaInfo(const ObjectAddress *object, bool missing_ok, - char **pubname, char **nspname, char **objtype) + char **pubname, char **nspname) { HeapTuple tup; Form_pg_publication_namespace pnform; @@ -2941,13 +2934,6 @@ getPublicationSchemaInfo(const ObjectAddress *object, bool missing_ok, return false; } - /* - * The type is always a single character, but we need to pass it as a string, - * so allocate two charaters and set the first one. The second one is \0. - */ - *objtype = palloc0(2); - *objtype[0] = pnform->pntype; - ReleaseSysCache(tup); return true; } @@ -3979,17 +3965,15 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) { char *pubname; char *nspname; - char *objtype; if (!getPublicationSchemaInfo(object, missing_ok, - &pubname, &nspname, &objtype)) + &pubname, &nspname)) break; - appendStringInfo(&buffer, _("publication of schema %s in publication %s type %s"), - nspname, pubname, objtype); + appendStringInfo(&buffer, _("publication of schema %s in publication %s"), + nspname, pubname); pfree(pubname); pfree(nspname); - pfree(objtype); break; } @@ -5816,24 +5800,18 @@ getObjectIdentityParts(const ObjectAddress *object, { char *pubname; char *nspname; - char *objtype; if (!getPublicationSchemaInfo(object, missing_ok, &pubname, - &nspname, &objtype)) + &nspname)) break; - appendStringInfo(&buffer, "%s in publication %s type %s", - nspname, pubname, objtype); + appendStringInfo(&buffer, "%s in publication %s", + nspname, pubname); if (objargs) *objargs = list_make1(pubname); else pfree(pubname); - if (objargs) - *objargs = lappend(*objargs, objtype); - else - pfree(objtype); - if (objname) *objname = list_make1(nspname); else diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 9fe3b189269..2631558ff11 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -55,10 +55,9 @@ static void publication_translate_columns(Relation targetrel, List *columns, static void check_publication_add_relation(Relation targetrel) { - /* Must be a regular or partitioned table, or a sequence */ + /* Must be a regular or partitioned table */ if (RelationGetForm(targetrel)->relkind != RELKIND_RELATION && - RelationGetForm(targetrel)->relkind != RELKIND_PARTITIONED_TABLE && - RelationGetForm(targetrel)->relkind != RELKIND_SEQUENCE) + RelationGetForm(targetrel)->relkind != RELKIND_PARTITIONED_TABLE) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot add relation \"%s\" to publication", @@ -135,8 +134,7 @@ static bool is_publishable_class(Oid relid, Form_pg_class reltuple) { return (reltuple->relkind == RELKIND_RELATION || - reltuple->relkind == RELKIND_PARTITIONED_TABLE || - reltuple->relkind == RELKIND_SEQUENCE) && + reltuple->relkind == RELKIND_PARTITIONED_TABLE) && !IsCatalogRelationOid(relid) && reltuple->relpersistence == RELPERSISTENCE_PERMANENT && relid >= FirstNormalObjectId; @@ -182,52 +180,6 @@ filter_partitions(List *relids) } /* - * Check the character is a valid object type for schema publication. - * - * This recognizes either 't' for tables or 's' for sequences. Places that - * need to handle 'u' for unsupported relkinds need to do that explicitlyl - */ -static void -AssertObjectTypeValid(char objectType) -{ -#ifdef USE_ASSERT_CHECKING - Assert(objectType == PUB_OBJTYPE_SEQUENCE || objectType == PUB_OBJTYPE_TABLE); -#endif -} - -/* - * Determine object type matching a given a relkind value. - */ -char -pub_get_object_type_for_relkind(char relkind) -{ - /* sequence maps directly to sequence relkind */ - if (relkind == RELKIND_SEQUENCE) - return PUB_OBJTYPE_SEQUENCE; - - /* for table, we match either regular or partitioned table */ - if (relkind == RELKIND_RELATION || - relkind == RELKIND_PARTITIONED_TABLE) - return PUB_OBJTYPE_TABLE; - - return PUB_OBJTYPE_UNSUPPORTED; -} - -/* - * Determine if publication object type matches the relkind. - * - * Returns true if the relation matches object type replicated by this schema, - * false otherwise. - */ -static bool -pub_object_type_matches_relkind(char objectType, char relkind) -{ - AssertObjectTypeValid(objectType); - - return (pub_get_object_type_for_relkind(relkind) == objectType); -} - -/* * Another variant of this, taking a Relation. */ bool @@ -256,7 +208,7 @@ is_schema_publication(Oid pubid) ObjectIdGetDatum(pubid)); scan = systable_beginscan(pubschsrel, - PublicationNamespacePnnspidPnpubidPntypeIndexId, + PublicationNamespacePnnspidPnpubidIndexId, true, NULL, 1, &scankey); tup = systable_getnext(scan); result = HeapTupleIsValid(tup); @@ -364,9 +316,7 @@ GetTopMostAncestorInPublication(Oid puboid, List *ancestors, int *ancestor_level } else { - /* we only search for ancestors of tables, so PUB_OBJTYPE_TABLE */ - aschemaPubids = GetSchemaPublications(get_rel_namespace(ancestor), - PUB_OBJTYPE_TABLE); + aschemaPubids = GetSchemaPublications(get_rel_namespace(ancestor)); if (list_member_oid(aschemaPubids, puboid)) { topmost_relid = ancestor; @@ -635,7 +585,7 @@ pub_collist_to_bitmapset(Bitmapset *columns, Datum pubcols, MemoryContext mcxt) * Insert new publication / schema mapping. */ ObjectAddress -publication_add_schema(Oid pubid, Oid schemaid, char objectType, bool if_not_exists) +publication_add_schema(Oid pubid, Oid schemaid, bool if_not_exists) { Relation rel; HeapTuple tup; @@ -647,8 +597,6 @@ publication_add_schema(Oid pubid, Oid schemaid, char objectType, bool if_not_exi ObjectAddress myself, referenced; - AssertObjectTypeValid(objectType); - rel = table_open(PublicationNamespaceRelationId, RowExclusiveLock); /* @@ -656,10 +604,9 @@ publication_add_schema(Oid pubid, Oid schemaid, char objectType, bool if_not_exi * duplicates, it's here just to provide nicer error message in common * case. The real protection is the unique key on the catalog. */ - if (SearchSysCacheExists3(PUBLICATIONNAMESPACEMAP, + if (SearchSysCacheExists2(PUBLICATIONNAMESPACEMAP, ObjectIdGetDatum(schemaid), - ObjectIdGetDatum(pubid), - CharGetDatum(objectType))) + ObjectIdGetDatum(pubid))) { table_close(rel, RowExclusiveLock); @@ -685,8 +632,6 @@ publication_add_schema(Oid pubid, Oid schemaid, char objectType, bool if_not_exi ObjectIdGetDatum(pubid); values[Anum_pg_publication_namespace_pnnspid - 1] = ObjectIdGetDatum(schemaid); - values[Anum_pg_publication_namespace_pntype - 1] = - CharGetDatum(objectType); tup = heap_form_tuple(RelationGetDescr(rel), values, nulls); @@ -712,7 +657,7 @@ publication_add_schema(Oid pubid, Oid schemaid, char objectType, bool if_not_exi * publication_add_relation for why we need to consider all the * partitions. */ - schemaRels = GetSchemaPublicationRelations(schemaid, objectType, + schemaRels = GetSchemaPublicationRelations(schemaid, PUBLICATION_PART_ALL); InvalidatePublicationRels(schemaRels); @@ -746,14 +691,11 @@ GetRelationPublications(Oid relid) /* * Gets list of relation oids for a publication. * - * This should only be used FOR TABLE / FOR SEQUENCE publications, the FOR - * ALL TABLES / SEQUENCES should use GetAllTablesPublicationRelations() - * and GetAllSequencesPublicationRelations(). - * - * XXX pub_partopt only matters for tables, not sequences. + * This should only be used FOR TABLE publications, the FOR ALL TABLES + * should use GetAllTablesPublicationRelations(). */ List * -GetPublicationRelations(Oid pubid, char objectType, PublicationPartOpt pub_partopt) +GetPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt) { List *result; Relation pubrelsrel; @@ -761,8 +703,6 @@ GetPublicationRelations(Oid pubid, char objectType, PublicationPartOpt pub_parto SysScanDesc scan; HeapTuple tup; - AssertObjectTypeValid(objectType); - /* Find all publications associated with the relation. */ pubrelsrel = table_open(PublicationRelRelationId, AccessShareLock); @@ -777,29 +717,11 @@ GetPublicationRelations(Oid pubid, char objectType, PublicationPartOpt pub_parto result = NIL; while (HeapTupleIsValid(tup = systable_getnext(scan))) { - char relkind; Form_pg_publication_rel pubrel; pubrel = (Form_pg_publication_rel) GETSTRUCT(tup); - relkind = get_rel_relkind(pubrel->prrelid); - - /* - * If the relkind does not match the requested object type, ignore the - * relation. For example we might be interested only in sequences, so - * we ignore tables. - */ - if (!pub_object_type_matches_relkind(objectType, relkind)) - continue; - - /* - * We don't have partitioned sequences, so just add them to the list. - * Otherwise consider adding all child relations, if requested. - */ - if (relkind == RELKIND_SEQUENCE) - result = lappend_oid(result, pubrel->prrelid); - else - result = GetPubPartitionOptionRelations(result, pub_partopt, - pubrel->prrelid); + result = GetPubPartitionOptionRelations(result, pub_partopt, + pubrel->prrelid); } systable_endscan(scan); @@ -850,43 +772,6 @@ GetAllTablesPublications(void) } /* - * Gets list of publication oids for publications marked as FOR ALL SEQUENCES. - */ -List * -GetAllSequencesPublications(void) -{ - List *result; - Relation rel; - ScanKeyData scankey; - SysScanDesc scan; - HeapTuple tup; - - /* Find all publications that are marked as for all sequences. */ - rel = table_open(PublicationRelationId, AccessShareLock); - - ScanKeyInit(&scankey, - Anum_pg_publication_puballsequences, - BTEqualStrategyNumber, F_BOOLEQ, - BoolGetDatum(true)); - - scan = systable_beginscan(rel, InvalidOid, false, - NULL, 1, &scankey); - - result = NIL; - while (HeapTupleIsValid(tup = systable_getnext(scan))) - { - Oid oid = ((Form_pg_publication) GETSTRUCT(tup))->oid; - - result = lappend_oid(result, oid); - } - - systable_endscan(scan); - table_close(rel, AccessShareLock); - - return result; -} - -/* * Gets list of all relation published by FOR ALL TABLES publication(s). * * If the publication publishes partition changes via their respective root @@ -952,38 +837,28 @@ GetAllTablesPublicationRelations(bool pubviaroot) /* * Gets the list of schema oids for a publication. * - * This should only be used FOR ALL TABLES IN SCHEMA and FOR ALL SEQUENCES - * publications. - * - * 'objectType' determines whether to get FOR TABLE or FOR SEQUENCES schemas + * This should only be used FOR ALL TABLES IN SCHEMA publications. */ List * -GetPublicationSchemas(Oid pubid, char objectType) +GetPublicationSchemas(Oid pubid) { List *result = NIL; Relation pubschsrel; - ScanKeyData scankey[2]; + ScanKeyData scankey; SysScanDesc scan; HeapTuple tup; - AssertObjectTypeValid(objectType); - /* Find all schemas associated with the publication */ pubschsrel = table_open(PublicationNamespaceRelationId, AccessShareLock); - ScanKeyInit(&scankey[0], + ScanKeyInit(&scankey, Anum_pg_publication_namespace_pnpubid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(pubid)); - ScanKeyInit(&scankey[1], - Anum_pg_publication_namespace_pntype, - BTEqualStrategyNumber, F_CHAREQ, - CharGetDatum(objectType)); - scan = systable_beginscan(pubschsrel, - PublicationNamespacePnnspidPnpubidPntypeIndexId, - true, NULL, 2, scankey); + PublicationNamespacePnnspidPnpubidIndexId, + true, NULL, 1, &scankey); while (HeapTupleIsValid(tup = systable_getnext(scan))) { Form_pg_publication_namespace pubsch; @@ -1001,26 +876,14 @@ GetPublicationSchemas(Oid pubid, char objectType) /* * Gets the list of publication oids associated with a specified schema. - * - * objectType specifies whether we're looking for schemas including tables or - * sequences. - * - * Note: relcache calls this for all object types, not just tables and sequences. - * Which is why we handle the PUB_OBJTYPE_UNSUPPORTED object type too. */ List * -GetSchemaPublications(Oid schemaid, char objectType) +GetSchemaPublications(Oid schemaid) { List *result = NIL; CatCList *pubschlist; int i; - /* unsupported object type */ - if (objectType == PUB_OBJTYPE_UNSUPPORTED) - return result; - - AssertObjectTypeValid(objectType); - /* Find all publications associated with the schema */ pubschlist = SearchSysCacheList1(PUBLICATIONNAMESPACEMAP, ObjectIdGetDatum(schemaid)); @@ -1028,11 +891,6 @@ GetSchemaPublications(Oid schemaid, char objectType) { HeapTuple tup = &pubschlist->members[i]->tuple; Oid pubid = ((Form_pg_publication_namespace) GETSTRUCT(tup))->pnpubid; - char pntype = ((Form_pg_publication_namespace) GETSTRUCT(tup))->pntype; - - /* Skip schemas publishing a different object type. */ - if (pntype != objectType) - continue; result = lappend_oid(result, pubid); } @@ -1044,13 +902,9 @@ GetSchemaPublications(Oid schemaid, char objectType) /* * Get the list of publishable relation oids for a specified schema. - * - * objectType specifies whether this is FOR ALL TABLES IN SCHEMA or FOR ALL - * SEQUENCES IN SCHEMA */ List * -GetSchemaPublicationRelations(Oid schemaid, char objectType, - PublicationPartOpt pub_partopt) +GetSchemaPublicationRelations(Oid schemaid, PublicationPartOpt pub_partopt) { Relation classRel; ScanKeyData key[1]; @@ -1059,7 +913,6 @@ GetSchemaPublicationRelations(Oid schemaid, char objectType, List *result = NIL; Assert(OidIsValid(schemaid)); - AssertObjectTypeValid(objectType); classRel = table_open(RelationRelationId, AccessShareLock); @@ -1080,16 +933,9 @@ GetSchemaPublicationRelations(Oid schemaid, char objectType, continue; relkind = get_rel_relkind(relid); - - /* Skip if the relkind does not match FOR ALL TABLES / SEQUENCES. */ - if (!pub_object_type_matches_relkind(objectType, relkind)) - continue; - - /* - * If the object is a partitioned table, lookup all the child relations - * (if requested). Otherwise just add the object to the list. - */ - if (relkind == RELKIND_PARTITIONED_TABLE) + if (relkind == RELKIND_RELATION) + result = lappend_oid(result, relid); + else if (relkind == RELKIND_PARTITIONED_TABLE) { List *partitionrels = NIL; @@ -1102,11 +948,7 @@ GetSchemaPublicationRelations(Oid schemaid, char objectType, pub_partopt, relForm->oid); result = list_concat_unique_oid(result, partitionrels); - continue; } - - /* non-partitioned tables and sequences */ - result = lappend_oid(result, relid); } table_endscan(scan); @@ -1116,25 +958,21 @@ GetSchemaPublicationRelations(Oid schemaid, char objectType, /* * Gets the list of all relations published by FOR ALL TABLES IN SCHEMA - * or FOR ALL SEQUENCES IN SCHEMA publication. + * publication. */ List * -GetAllSchemaPublicationRelations(Oid pubid, char objectType, - PublicationPartOpt pub_partopt) +GetAllSchemaPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt) { List *result = NIL; - List *pubschemalist = GetPublicationSchemas(pubid, objectType); + List *pubschemalist = GetPublicationSchemas(pubid); ListCell *cell; - AssertObjectTypeValid(objectType); - foreach(cell, pubschemalist) { Oid schemaid = lfirst_oid(cell); List *schemaRels = NIL; - schemaRels = GetSchemaPublicationRelations(schemaid, objectType, - pub_partopt); + schemaRels = GetSchemaPublicationRelations(schemaid, pub_partopt); result = list_concat(result, schemaRels); } @@ -1142,42 +980,6 @@ GetAllSchemaPublicationRelations(Oid pubid, char objectType, } /* - * 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 * * The Publication struct and its data are palloc'ed here. @@ -1199,12 +1001,10 @@ 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; pub->pubactions.pubtruncate = pubform->pubtruncate; - pub->pubactions.pubsequence = pubform->pubsequence; pub->pubviaroot = pubform->pubviaroot; ReleaseSysCache(tup); @@ -1315,12 +1115,10 @@ pg_get_publication_tables(PG_FUNCTION_ARGS) *schemarelids; relids = GetPublicationRelations(publication->oid, - PUB_OBJTYPE_TABLE, publication->pubviaroot ? PUBLICATION_PART_ROOT : PUBLICATION_PART_LEAF); schemarelids = GetAllSchemaPublicationRelations(publication->oid, - PUB_OBJTYPE_TABLE, publication->pubviaroot ? PUBLICATION_PART_ROOT : PUBLICATION_PART_LEAF); @@ -1356,71 +1154,3 @@ 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); - - /* - * Publications support partitioned tables, although all changes are - * replicated using leaf partition identity and schema, so we only - * need those. - */ - if (publication->allsequences) - sequences = GetAllSequencesPublicationRelations(); - else - { - List *relids, - *schemarelids; - - relids = GetPublicationRelations(publication->oid, - PUB_OBJTYPE_SEQUENCE, - publication->pubviaroot ? - PUBLICATION_PART_ROOT : - PUBLICATION_PART_LEAF); - schemarelids = GetAllSchemaPublicationRelations(publication->oid, - PUB_OBJTYPE_SEQUENCE, - publication->pubviaroot ? - PUBLICATION_PART_ROOT : - PUBLICATION_PART_LEAF); - sequences = list_concat_unique_oid(relids, schemarelids); - } - - 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 b1a6df16ad3..0fc614e32c0 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -374,16 +374,6 @@ 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 84e37df783b..4fd1e6e7abb 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -16,7 +16,6 @@ #include "access/genam.h" #include "access/htup_details.h" -#include "access/relation.h" #include "access/table.h" #include "access/xact.h" #include "catalog/catalog.h" @@ -68,17 +67,15 @@ typedef struct rf_context } rf_context; static List *OpenRelIdList(List *relids); -static List *OpenRelationList(List *rels, char objectType); -static void CloseRelationList(List *rels); +static List *OpenTableList(List *tables); +static void CloseTableList(List *rels); static void LockSchemaList(List *schemalist); -static void PublicationAddRelations(Oid pubid, List *rels, bool if_not_exists, +static void PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, AlterPublicationStmt *stmt); -static void PublicationDropRelations(Oid pubid, List *rels, bool missing_ok); -static void PublicationAddSchemas(Oid pubid, List *schemas, char objectType, - bool if_not_exists, AlterPublicationStmt *stmt); -static void PublicationDropSchemas(Oid pubid, List *schemas, char objectType, - bool missing_ok); - +static void PublicationDropTables(Oid pubid, List *rels, bool missing_ok); +static void PublicationAddSchemas(Oid pubid, List *schemas, bool if_not_exists, + AlterPublicationStmt *stmt); +static void PublicationDropSchemas(Oid pubid, List *schemas, bool missing_ok); static void parse_publication_options(ParseState *pstate, @@ -98,7 +95,6 @@ parse_publication_options(ParseState *pstate, pubactions->pubupdate = true; pubactions->pubdelete = true; pubactions->pubtruncate = true; - pubactions->pubsequence = true; *publish_via_partition_root = false; /* Parse options */ @@ -123,7 +119,6 @@ parse_publication_options(ParseState *pstate, pubactions->pubupdate = false; pubactions->pubdelete = false; pubactions->pubtruncate = false; - pubactions->pubsequence = false; *publish_given = true; publish = defGetString(defel); @@ -146,8 +141,6 @@ parse_publication_options(ParseState *pstate, pubactions->pubdelete = true; else if (strcmp(publish_opt, "truncate") == 0) pubactions->pubtruncate = true; - else if (strcmp(publish_opt, "sequence") == 0) - pubactions->pubsequence = true; else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), @@ -174,8 +167,7 @@ parse_publication_options(ParseState *pstate, */ static void ObjectsInPublicationToOids(List *pubobjspec_list, ParseState *pstate, - List **tables, List **sequences, - List **tables_schemas, List **sequences_schemas) + List **rels, List **schemas) { ListCell *cell; PublicationObjSpec *pubobj; @@ -193,22 +185,13 @@ ObjectsInPublicationToOids(List *pubobjspec_list, ParseState *pstate, switch (pubobj->pubobjtype) { case PUBLICATIONOBJ_TABLE: - *tables = lappend(*tables, pubobj->pubtable); - break; - case PUBLICATIONOBJ_SEQUENCE: - *sequences = lappend(*sequences, pubobj->pubtable); + *rels = lappend(*rels, pubobj->pubtable); break; case PUBLICATIONOBJ_TABLES_IN_SCHEMA: schemaid = get_namespace_oid(pubobj->name, false); /* Filter out duplicates if user specifies "sch1, sch1" */ - *tables_schemas = list_append_unique_oid(*tables_schemas, schemaid); - break; - case PUBLICATIONOBJ_SEQUENCES_IN_SCHEMA: - schemaid = get_namespace_oid(pubobj->name, false); - - /* Filter out duplicates if user specifies "sch1, sch1" */ - *sequences_schemas = list_append_unique_oid(*sequences_schemas, schemaid); + *schemas = list_append_unique_oid(*schemas, schemaid); break; case PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA: search_path = fetch_search_path(false); @@ -221,20 +204,7 @@ ObjectsInPublicationToOids(List *pubobjspec_list, ParseState *pstate, list_free(search_path); /* Filter out duplicates if user specifies "sch1, sch1" */ - *tables_schemas = list_append_unique_oid(*tables_schemas, schemaid); - break; - case PUBLICATIONOBJ_SEQUENCES_IN_CUR_SCHEMA: - search_path = fetch_search_path(false); - if (search_path == NIL) /* nothing valid in search_path? */ - ereport(ERROR, - errcode(ERRCODE_UNDEFINED_SCHEMA), - errmsg("no schema has been selected for CURRENT_SCHEMA")); - - schemaid = linitial_oid(search_path); - list_free(search_path); - - /* Filter out duplicates if user specifies "sch1, sch1" */ - *sequences_schemas = list_append_unique_oid(*sequences_schemas, schemaid); + *schemas = list_append_unique_oid(*schemas, schemaid); break; default: /* shouldn't happen */ @@ -270,14 +240,6 @@ CheckObjSchemaNotAlreadyInPublication(List *rels, List *schemaidlist, errdetail("Table \"%s\" in schema \"%s\" is already part of the publication, adding the same schema is not supported.", RelationGetRelationName(rel), get_namespace_name(relSchemaId))); - else if (checkobjtype == PUBLICATIONOBJ_SEQUENCES_IN_SCHEMA) - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot add schema \"%s\" to publication", - get_namespace_name(relSchemaId)), - errdetail("Sequence \"%s\" in schema \"%s\" is already part of the publication, adding the same schema is not supported.", - RelationGetRelationName(rel), - get_namespace_name(relSchemaId))); else if (checkobjtype == PUBLICATIONOBJ_TABLE) ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -286,14 +248,6 @@ CheckObjSchemaNotAlreadyInPublication(List *rels, List *schemaidlist, RelationGetRelationName(rel)), errdetail("Table's schema \"%s\" is already part of the publication or part of the specified schema list.", get_namespace_name(relSchemaId))); - else if (checkobjtype == PUBLICATIONOBJ_SEQUENCE) - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot add relation \"%s.%s\" to publication", - get_namespace_name(relSchemaId), - RelationGetRelationName(rel)), - errdetail("Sequence's schema \"%s\" is already part of the publication or part of the specified schema list.", - get_namespace_name(relSchemaId))); } } } @@ -799,7 +753,6 @@ CheckPubRelationColumnList(List *tables, const char *queryString, ObjectAddress CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) { - ListCell *lc; Relation rel; ObjectAddress myself; Oid puboid; @@ -811,23 +764,8 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) bool publish_via_partition_root_given; bool publish_via_partition_root; AclResult aclresult; - List *tables = NIL; - List *sequences = NIL; - List *tables_schemaidlist = NIL; - List *sequences_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; - } + List *relations = NIL; + List *schemaidlist = NIL; /* must have CREATE privilege on database */ aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE); @@ -836,17 +774,11 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) get_database_name(MyDatabaseId)); /* FOR ALL TABLES requires superuser */ - if (for_all_tables && !superuser()) + if (stmt->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 */ @@ -878,9 +810,7 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) Anum_pg_publication_oid); values[Anum_pg_publication_oid - 1] = ObjectIdGetDatum(puboid); values[Anum_pg_publication_puballtables - 1] = - BoolGetDatum(for_all_tables); - values[Anum_pg_publication_puballsequences - 1] = - BoolGetDatum(for_all_sequences); + BoolGetDatum(stmt->for_all_tables); values[Anum_pg_publication_pubinsert - 1] = BoolGetDatum(pubactions.pubinsert); values[Anum_pg_publication_pubupdate - 1] = @@ -889,8 +819,6 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) BoolGetDatum(pubactions.pubdelete); values[Anum_pg_publication_pubtruncate - 1] = BoolGetDatum(pubactions.pubtruncate); - values[Anum_pg_publication_pubsequence - 1] = - BoolGetDatum(pubactions.pubsequence); values[Anum_pg_publication_pubviaroot - 1] = BoolGetDatum(publish_via_partition_root); @@ -908,42 +836,28 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) CommandCounterIncrement(); /* Associate objects with the publication. */ - if (for_all_tables || for_all_sequences) + if (stmt->for_all_tables) { /* Invalidate relcache so that publication info is rebuilt. */ CacheInvalidateRelcacheAll(); } - - /* - * If the publication might have either tables or sequences (directly or - * through a schema), process that. - */ - if (!for_all_tables || !for_all_sequences) + else { - ObjectsInPublicationToOids(stmt->pubobjects, pstate, - &tables, &sequences, - &tables_schemaidlist, - &sequences_schemaidlist); + ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations, + &schemaidlist); /* FOR ALL TABLES IN SCHEMA requires superuser */ - if (list_length(tables_schemaidlist) > 0 && !superuser()) + if (list_length(schemaidlist) > 0 && !superuser()) ereport(ERROR, errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to create FOR ALL TABLES IN SCHEMA publication")); - /* FOR ALL SEQUENCES IN SCHEMA requires superuser */ - if (list_length(sequences_schemaidlist) > 0 && !superuser()) - ereport(ERROR, - errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to create FOR ALL SEQUENCES IN SCHEMA publication")); - - /* tables added directly */ - if (list_length(tables) > 0) + if (list_length(relations) > 0) { List *rels; - rels = OpenRelationList(tables, PUB_OBJTYPE_TABLE); - CheckObjSchemaNotAlreadyInPublication(rels, tables_schemaidlist, + rels = OpenTableList(relations); + CheckObjSchemaNotAlreadyInPublication(rels, schemaidlist, PUBLICATIONOBJ_TABLE); TransformPubWhereClauses(rels, pstate->p_sourcetext, @@ -952,46 +866,18 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) CheckPubRelationColumnList(rels, pstate->p_sourcetext, publish_via_partition_root); - PublicationAddRelations(puboid, rels, true, NULL); - CloseRelationList(rels); + PublicationAddTables(puboid, rels, true, NULL); + CloseTableList(rels); } - /* sequences added directly */ - if (list_length(sequences) > 0) - { - List *rels; - - rels = OpenRelationList(sequences, PUB_OBJTYPE_SEQUENCE); - CheckObjSchemaNotAlreadyInPublication(rels, sequences_schemaidlist, - PUBLICATIONOBJ_SEQUENCE); - PublicationAddRelations(puboid, rels, true, NULL); - CloseRelationList(rels); - } - - /* tables added through a schema */ - if (list_length(tables_schemaidlist) > 0) + if (list_length(schemaidlist) > 0) { /* * Schema lock is held until the publication is created to prevent * concurrent schema deletion. */ - LockSchemaList(tables_schemaidlist); - PublicationAddSchemas(puboid, - tables_schemaidlist, PUB_OBJTYPE_TABLE, - true, NULL); - } - - /* sequences added through a schema */ - if (list_length(sequences_schemaidlist) > 0) - { - /* - * Schema lock is held until the publication is created to prevent - * concurrent schema deletion. - */ - LockSchemaList(sequences_schemaidlist); - PublicationAddSchemas(puboid, - sequences_schemaidlist, PUB_OBJTYPE_SEQUENCE, - true, NULL); + LockSchemaList(schemaidlist); + PublicationAddSchemas(puboid, schemaidlist, true, NULL); } } @@ -1055,7 +941,6 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, AccessShareLock); root_relids = GetPublicationRelations(pubform->oid, - PUB_OBJTYPE_TABLE, PUBLICATION_PART_ROOT); foreach(lc, root_relids) @@ -1135,9 +1020,6 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, values[Anum_pg_publication_pubtruncate - 1] = BoolGetDatum(pubactions.pubtruncate); replaces[Anum_pg_publication_pubtruncate - 1] = true; - - values[Anum_pg_publication_pubsequence - 1] = BoolGetDatum(pubactions.pubsequence); - replaces[Anum_pg_publication_pubsequence - 1] = true; } if (publish_via_partition_root_given) @@ -1157,7 +1039,7 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, pubform = (Form_pg_publication) GETSTRUCT(tup); /* Invalidate the relcache. */ - if (pubform->puballtables || pubform->puballsequences) + if (pubform->puballtables) { CacheInvalidateRelcacheAll(); } @@ -1173,7 +1055,6 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, */ if (root_relids == NIL) relids = GetPublicationRelations(pubform->oid, - PUB_OBJTYPE_TABLE, PUBLICATION_PART_ALL); else { @@ -1187,20 +1068,7 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, lfirst_oid(lc)); } - /* tables */ - schemarelids = GetAllSchemaPublicationRelations(pubform->oid, - PUB_OBJTYPE_TABLE, - PUBLICATION_PART_ALL); - relids = list_concat_unique_oid(relids, schemarelids); - - /* sequences */ - relids = list_concat_unique_oid(relids, - GetPublicationRelations(pubform->oid, - PUB_OBJTYPE_SEQUENCE, - PUBLICATION_PART_ALL)); - schemarelids = GetAllSchemaPublicationRelations(pubform->oid, - PUB_OBJTYPE_SEQUENCE, PUBLICATION_PART_ALL); relids = list_concat_unique_oid(relids, schemarelids); @@ -1255,7 +1123,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup, if (!tables && stmt->action != AP_SetObjects) return; - rels = OpenRelationList(tables, PUB_OBJTYPE_TABLE); + rels = OpenTableList(tables); if (stmt->action == AP_AddObjects) { @@ -1265,9 +1133,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup, * Check if the relation is member of the existing schema in the * publication or member of the schema list specified. */ - schemas = list_concat_copy(schemaidlist, - GetPublicationSchemas(pubid, - PUB_OBJTYPE_TABLE)); + schemas = list_concat_copy(schemaidlist, GetPublicationSchemas(pubid)); CheckObjSchemaNotAlreadyInPublication(rels, schemas, PUBLICATIONOBJ_TABLE); @@ -1275,14 +1141,13 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup, CheckPubRelationColumnList(rels, queryString, pubform->pubviaroot); - PublicationAddRelations(pubid, rels, false, stmt); + PublicationAddTables(pubid, rels, false, stmt); } else if (stmt->action == AP_DropObjects) - PublicationDropRelations(pubid, rels, false); + PublicationDropTables(pubid, rels, false); else /* AP_SetObjects */ { List *oldrelids = GetPublicationRelations(pubid, - PUB_OBJTYPE_TABLE, PUBLICATION_PART_ROOT); List *delrels = NIL; ListCell *oldlc; @@ -1401,18 +1266,18 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup, } /* And drop them. */ - PublicationDropRelations(pubid, delrels, true); + PublicationDropTables(pubid, delrels, true); /* * Don't bother calculating the difference for adding, we'll catch and * skip existing ones when doing catalog update. */ - PublicationAddRelations(pubid, rels, true, stmt); + PublicationAddTables(pubid, rels, true, stmt); - CloseRelationList(delrels); + CloseTableList(delrels); } - CloseRelationList(rels); + CloseTableList(rels); } /* @@ -1422,8 +1287,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup, */ static void AlterPublicationSchemas(AlterPublicationStmt *stmt, - HeapTuple tup, List *schemaidlist, - char objectType) + HeapTuple tup, List *schemaidlist) { Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup); @@ -1445,20 +1309,20 @@ AlterPublicationSchemas(AlterPublicationStmt *stmt, List *rels; List *reloids; - reloids = GetPublicationRelations(pubform->oid, objectType, PUBLICATION_PART_ROOT); + reloids = GetPublicationRelations(pubform->oid, PUBLICATION_PART_ROOT); rels = OpenRelIdList(reloids); CheckObjSchemaNotAlreadyInPublication(rels, schemaidlist, PUBLICATIONOBJ_TABLES_IN_SCHEMA); - CloseRelationList(rels); - PublicationAddSchemas(pubform->oid, schemaidlist, objectType, false, stmt); + CloseTableList(rels); + PublicationAddSchemas(pubform->oid, schemaidlist, false, stmt); } else if (stmt->action == AP_DropObjects) - PublicationDropSchemas(pubform->oid, schemaidlist, objectType, false); + PublicationDropSchemas(pubform->oid, schemaidlist, false); else /* AP_SetObjects */ { - List *oldschemaids = GetPublicationSchemas(pubform->oid, objectType); + List *oldschemaids = GetPublicationSchemas(pubform->oid); List *delschemas = NIL; /* Identify which schemas should be dropped */ @@ -1471,13 +1335,13 @@ AlterPublicationSchemas(AlterPublicationStmt *stmt, LockSchemaList(delschemas); /* And drop them */ - PublicationDropSchemas(pubform->oid, delschemas, objectType, true); + PublicationDropSchemas(pubform->oid, delschemas, true); /* * Don't bother calculating the difference for adding, we'll catch and * skip existing ones when doing catalog update. */ - PublicationAddSchemas(pubform->oid, schemaidlist, objectType, true, stmt); + PublicationAddSchemas(pubform->oid, schemaidlist, true, stmt); } } @@ -1487,13 +1351,12 @@ AlterPublicationSchemas(AlterPublicationStmt *stmt, */ static void CheckAlterPublication(AlterPublicationStmt *stmt, HeapTuple tup, - List *tables, List *tables_schemaidlist, - List *sequences, List *sequences_schemaidlist) + List *tables, List *schemaidlist) { Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup); if ((stmt->action == AP_AddObjects || stmt->action == AP_SetObjects) && - (tables_schemaidlist || sequences_schemaidlist) && !superuser()) + schemaidlist && !superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to add or set schemas"))); @@ -1502,24 +1365,13 @@ CheckAlterPublication(AlterPublicationStmt *stmt, HeapTuple tup, * Check that user is allowed to manipulate the publication tables in * schema */ - if (tables_schemaidlist && pubform->puballtables) + if (schemaidlist && pubform->puballtables) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("publication \"%s\" is defined as FOR ALL TABLES", NameStr(pubform->pubname)), errdetail("Tables from schema cannot be added to, dropped from, or set on FOR ALL TABLES publications."))); - /* - * Check that user is allowed to manipulate the publication sequences in - * schema - */ - if (sequences_schemaidlist && pubform->puballsequences) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("publication \"%s\" is defined as FOR ALL SEQUENCES", - NameStr(pubform->pubname)), - errdetail("Sequences from schema cannot be added to, dropped from, or set on FOR ALL SEQUENCES publications."))); - /* Check that user is allowed to manipulate the publication tables. */ if (tables && pubform->puballtables) ereport(ERROR, @@ -1527,108 +1379,6 @@ CheckAlterPublication(AlterPublicationStmt *stmt, HeapTuple tup, errmsg("publication \"%s\" is defined as FOR ALL TABLES", NameStr(pubform->pubname)), errdetail("Tables cannot be added to or dropped from FOR ALL TABLES publications."))); - - /* Check that user is allowed to manipulate the publication sequences. */ - if (sequences && pubform->puballsequences) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("publication \"%s\" is defined as FOR ALL SEQUENCES", - NameStr(pubform->pubname)), - errdetail("Sequences cannot be added to or dropped from FOR ALL SEQUENCES publications."))); -} - -/* - * Add or remove sequence to/from publication. - */ -static void -AlterPublicationSequences(AlterPublicationStmt *stmt, HeapTuple tup, - List *sequences, List *schemaidlist) -{ - List *rels = NIL; - Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup); - Oid pubid = pubform->oid; - - /* - * It is quite possible that for the SET case user has not specified any - * tables in which case we need to remove all the existing tables. - */ - if (!sequences && stmt->action != AP_SetObjects) - return; - - rels = OpenRelationList(sequences, PUB_OBJTYPE_SEQUENCE); - - if (stmt->action == AP_AddObjects) - { - List *schemas = NIL; - - /* - * Check if the relation is member of the existing schema in the - * publication or member of the schema list specified. - */ - schemas = list_concat_copy(schemaidlist, - GetPublicationSchemas(pubid, - PUB_OBJTYPE_SEQUENCE)); - CheckObjSchemaNotAlreadyInPublication(rels, schemas, - PUBLICATIONOBJ_SEQUENCE); - PublicationAddRelations(pubid, rels, false, stmt); - } - else if (stmt->action == AP_DropObjects) - PublicationDropRelations(pubid, rels, false); - else /* DEFELEM_SET */ - { - List *oldrelids = GetPublicationRelations(pubid, - PUB_OBJTYPE_SEQUENCE, - PUBLICATION_PART_ROOT); - List *delrels = NIL; - ListCell *oldlc; - - CheckObjSchemaNotAlreadyInPublication(rels, schemaidlist, - PUBLICATIONOBJ_SEQUENCE); - - /* Calculate which relations to drop. */ - foreach(oldlc, oldrelids) - { - Oid oldrelid = lfirst_oid(oldlc); - ListCell *newlc; - PublicationRelInfo *oldrel; - bool found = false; - - foreach(newlc, rels) - { - PublicationRelInfo *newpubrel; - - newpubrel = (PublicationRelInfo *) lfirst(newlc); - if (RelationGetRelid(newpubrel->relation) == oldrelid) - { - found = true; - break; - } - } - /* Not yet in the list, open it and add to the list */ - if (!found) - { - oldrel = palloc(sizeof(PublicationRelInfo)); - oldrel->whereClause = NULL; - oldrel->columns = NULL; - oldrel->relation = table_open(oldrelid, - ShareUpdateExclusiveLock); - delrels = lappend(delrels, oldrel); - } - } - - /* And drop them. */ - PublicationDropRelations(pubid, delrels, true); - - /* - * Don't bother calculating the difference for adding, we'll catch and - * skip existing ones when doing catalog update. - */ - PublicationAddRelations(pubid, rels, true, stmt); - - CloseRelationList(delrels); - } - - CloseRelationList(rels); } /* @@ -1666,20 +1416,14 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt) AlterPublicationOptions(pstate, stmt, rel, tup); else { - List *tables = NIL; - List *sequences = NIL; - List *tables_schemaidlist = NIL; - List *sequences_schemaidlist = NIL; + List *relations = NIL; + List *schemaidlist = NIL; Oid pubid = pubform->oid; - ObjectsInPublicationToOids(stmt->pubobjects, pstate, - &tables, &sequences, - &tables_schemaidlist, - &sequences_schemaidlist); + ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations, + &schemaidlist); - CheckAlterPublication(stmt, tup, - tables, tables_schemaidlist, - sequences, sequences_schemaidlist); + CheckAlterPublication(stmt, tup, relations, schemaidlist); heap_freetuple(tup); @@ -1707,16 +1451,9 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt) errmsg("publication \"%s\" does not exist", stmt->pubname)); - AlterPublicationTables(stmt, tup, tables, tables_schemaidlist, + AlterPublicationTables(stmt, tup, relations, schemaidlist, pstate->p_sourcetext); - - AlterPublicationSequences(stmt, tup, sequences, sequences_schemaidlist); - - AlterPublicationSchemas(stmt, tup, tables_schemaidlist, - PUB_OBJTYPE_TABLE); - - AlterPublicationSchemas(stmt, tup, sequences_schemaidlist, - PUB_OBJTYPE_SEQUENCE); + AlterPublicationSchemas(stmt, tup, schemaidlist); } /* Cleanup. */ @@ -1784,7 +1521,7 @@ RemovePublicationById(Oid pubid) pubform = (Form_pg_publication) GETSTRUCT(tup); /* Invalidate relcache so that publication info is rebuilt. */ - if (pubform->puballtables || pubform->puballsequences) + if (pubform->puballtables) CacheInvalidateRelcacheAll(); CatalogTupleDelete(rel, &tup->t_self); @@ -1820,7 +1557,6 @@ RemovePublicationSchemaById(Oid psoid) * partitions. */ schemaRels = GetSchemaPublicationRelations(pubsch->pnnspid, - pubsch->pntype, PUBLICATION_PART_ALL); InvalidatePublicationRels(schemaRels); @@ -1863,10 +1599,10 @@ OpenRelIdList(List *relids) * add them to a publication. */ static List * -OpenRelationList(List *rels, char objectType) +OpenTableList(List *tables) { List *relids = NIL; - List *result = NIL; + List *rels = NIL; ListCell *lc; List *relids_with_rf = NIL; List *relids_with_collist = NIL; @@ -1874,35 +1610,19 @@ OpenRelationList(List *rels, char objectType) /* * Open, share-lock, and check all the explicitly-specified relations */ - foreach(lc, rels) + foreach(lc, tables) { PublicationTable *t = lfirst_node(PublicationTable, lc); bool recurse = t->relation->inh; Relation rel; Oid myrelid; PublicationRelInfo *pub_rel; - char myrelkind; /* Allow query cancel in case this takes a long time */ CHECK_FOR_INTERRUPTS(); rel = table_openrv(t->relation, ShareUpdateExclusiveLock); myrelid = RelationGetRelid(rel); - myrelkind = get_rel_relkind(myrelid); - - /* - * Make sure the relkind matches the expected object type. This may - * happen e.g. when adding a sequence using ADD TABLE or a table - * using ADD SEQUENCE). - * - * XXX We let through unsupported object types (views etc.). Those - * will be caught later in check_publication_add_relation. - */ - if (pub_get_object_type_for_relkind(myrelkind) != PUB_OBJTYPE_UNSUPPORTED && - pub_get_object_type_for_relkind(myrelkind) != objectType) - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("object type does not match type expected by command")); /* * Filter out duplicates if user specifies "foo, foo". @@ -1935,7 +1655,7 @@ OpenRelationList(List *rels, char objectType) pub_rel->relation = rel; pub_rel->whereClause = t->whereClause; pub_rel->columns = t->columns; - result = lappend(result, pub_rel); + rels = lappend(rels, pub_rel); relids = lappend_oid(relids, myrelid); if (t->whereClause) @@ -2004,9 +1724,10 @@ OpenRelationList(List *rels, char objectType) pub_rel->relation = rel; /* child inherits WHERE clause from parent */ pub_rel->whereClause = t->whereClause; + /* child inherits column list from parent */ pub_rel->columns = t->columns; - result = lappend(result, pub_rel); + rels = lappend(rels, pub_rel); relids = lappend_oid(relids, childrelid); if (t->whereClause) @@ -2021,14 +1742,14 @@ OpenRelationList(List *rels, char objectType) list_free(relids); list_free(relids_with_rf); - return result; + return rels; } /* * Close all relations in the list. */ static void -CloseRelationList(List *rels) +CloseTableList(List *rels) { ListCell *lc; @@ -2076,12 +1797,12 @@ LockSchemaList(List *schemalist) * Add listed tables to the publication. */ static void -PublicationAddRelations(Oid pubid, List *rels, bool if_not_exists, +PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, AlterPublicationStmt *stmt) { ListCell *lc; - Assert(!stmt || !stmt->for_all_objects); + Assert(!stmt || !stmt->for_all_tables); foreach(lc, rels) { @@ -2110,7 +1831,7 @@ PublicationAddRelations(Oid pubid, List *rels, bool if_not_exists, * Remove listed tables from the publication. */ static void -PublicationDropRelations(Oid pubid, List *rels, bool missing_ok) +PublicationDropTables(Oid pubid, List *rels, bool missing_ok) { ObjectAddress obj; ListCell *lc; @@ -2155,19 +1876,19 @@ PublicationDropRelations(Oid pubid, List *rels, bool missing_ok) * Add listed schemas to the publication. */ static void -PublicationAddSchemas(Oid pubid, List *schemas, char objectType, - bool if_not_exists, AlterPublicationStmt *stmt) +PublicationAddSchemas(Oid pubid, List *schemas, bool if_not_exists, + AlterPublicationStmt *stmt) { ListCell *lc; - Assert(!stmt || !stmt->for_all_objects); + Assert(!stmt || !stmt->for_all_tables); foreach(lc, schemas) { Oid schemaid = lfirst_oid(lc); ObjectAddress obj; - obj = publication_add_schema(pubid, schemaid, objectType, if_not_exists); + obj = publication_add_schema(pubid, schemaid, if_not_exists); if (stmt) { EventTriggerCollectSimpleCommand(obj, InvalidObjectAddress, @@ -2183,7 +1904,7 @@ PublicationAddSchemas(Oid pubid, List *schemas, char objectType, * Remove listed schemas from the publication. */ static void -PublicationDropSchemas(Oid pubid, List *schemas, char objectType, bool missing_ok) +PublicationDropSchemas(Oid pubid, List *schemas, bool missing_ok) { ObjectAddress obj; ListCell *lc; @@ -2193,11 +1914,10 @@ PublicationDropSchemas(Oid pubid, List *schemas, char objectType, bool missing_o { Oid schemaid = lfirst_oid(lc); - psid = GetSysCacheOid3(PUBLICATIONNAMESPACEMAP, + psid = GetSysCacheOid2(PUBLICATIONNAMESPACEMAP, Anum_pg_publication_namespace_oid, ObjectIdGetDatum(schemaid), - ObjectIdGetDatum(pubid), - CharGetDatum(objectType)); + ObjectIdGetDatum(pubid)); if (!OidIsValid(psid)) { if (missing_ok) @@ -2252,13 +1972,6 @@ 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/commands/sequence.c b/src/backend/commands/sequence.c index 47f62c28d42..ddf219b21f5 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -333,160 +333,6 @@ ResetSequence(Oid seq_relid) } /* - * Update the sequence state by modifying the existing sequence data row. - * - * This keeps the same relfilenode, so the behavior is non-transactional. - */ -static void -SetSequence_non_transactional(Oid seqrelid, int64 last_value, int64 log_cnt, bool is_called) -{ - SeqTable elm; - Relation seqrel; - Buffer buf; - HeapTupleData seqdatatuple; - Form_pg_sequence_data seq; - - /* open and lock sequence */ - init_sequence(seqrelid, &elm, &seqrel); - - /* lock page' buffer and read tuple */ - seq = read_seq_tuple(seqrel, &buf, &seqdatatuple); - - /* check the comment above nextval_internal()'s equivalent call. */ - if (RelationNeedsWAL(seqrel)) - { - GetTopTransactionId(); - - if (XLogLogicalInfoActive()) - GetCurrentTransactionId(); - } - - /* ready to change the on-disk (or really, in-buffer) tuple */ - START_CRIT_SECTION(); - - seq->last_value = last_value; - seq->is_called = is_called; - seq->log_cnt = log_cnt; - - MarkBufferDirty(buf); - - /* XLOG stuff */ - if (RelationNeedsWAL(seqrel)) - { - xl_seq_rec xlrec; - XLogRecPtr recptr; - Page page = BufferGetPage(buf); - - XLogBeginInsert(); - XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT); - - xlrec.node = seqrel->rd_node; - xlrec.created = false; - - XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec)); - XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len); - - recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG); - - PageSetLSN(page, recptr); - } - - END_CRIT_SECTION(); - - UnlockReleaseBuffer(buf); - - /* Clear local cache so that we don't think we have cached numbers */ - /* Note that we do not change the currval() state */ - elm->cached = elm->last; - - relation_close(seqrel, NoLock); -} - -/* - * Update the sequence state by creating a new relfilenode. - * - * This creates a new relfilenode, to allow transactional behavior. - */ -static void -SetSequence_transactional(Oid seq_relid, int64 last_value, int64 log_cnt, bool is_called) -{ - SeqTable elm; - Relation seqrel; - Buffer buf; - HeapTupleData seqdatatuple; - Form_pg_sequence_data seq; - HeapTuple tuple; - - /* open and lock sequence */ - init_sequence(seq_relid, &elm, &seqrel); - - /* lock page' buffer and read tuple */ - seq = read_seq_tuple(seqrel, &buf, &seqdatatuple); - - /* Copy the existing sequence tuple. */ - tuple = heap_copytuple(&seqdatatuple); - - /* Now we're done with the old page */ - UnlockReleaseBuffer(buf); - - /* - * Modify the copied tuple to update the sequence state (similar to what - * ResetSequence does). - */ - seq = (Form_pg_sequence_data) GETSTRUCT(tuple); - seq->last_value = last_value; - seq->is_called = is_called; - seq->log_cnt = log_cnt; - - /* - * Create a new storage file for the sequence - this is needed for the - * transactional behavior. - */ - RelationSetNewRelfilenode(seqrel, seqrel->rd_rel->relpersistence); - - /* - * Ensure sequence's relfrozenxid is at 0, since it won't contain any - * unfrozen XIDs. Same with relminmxid, since a sequence will never - * contain multixacts. - */ - Assert(seqrel->rd_rel->relfrozenxid == InvalidTransactionId); - Assert(seqrel->rd_rel->relminmxid == InvalidMultiXactId); - - /* - * Insert the modified tuple into the new storage file. This does all the - * necessary WAL-logging etc. - */ - fill_seq_with_data(seqrel, tuple); - - /* Clear local cache so that we don't think we have cached numbers */ - /* Note that we do not change the currval() state */ - elm->cached = elm->last; - - relation_close(seqrel, NoLock); -} - -/* - * Set a sequence to a specified internal state. - * - * The change is made transactionally, so that on failure of the current - * transaction, the sequence will be restored to its previous state. - * We do that by creating a whole new relfilenode for the sequence; so this - * works much like the rewriting forms of ALTER TABLE. - * - * Caller is assumed to have acquired AccessExclusiveLock on the sequence, - * which must not be released until end of transaction. Caller is also - * responsible for permissions checking. - */ -void -SetSequence(Oid seq_relid, bool transactional, int64 last_value, int64 log_cnt, bool is_called) -{ - if (transactional) - SetSequence_transactional(seq_relid, last_value, log_cnt, is_called); - else - SetSequence_non_transactional(seq_relid, last_value, log_cnt, is_called); -} - -/* * Initialize a sequence's relation with the specified tuple as content * * This handles unlogged sequences by writing to both the main and the init @@ -552,13 +398,8 @@ fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum) /* check the comment above nextval_internal()'s equivalent call. */ if (RelationNeedsWAL(rel)) - { GetTopTransactionId(); - if (XLogLogicalInfoActive()) - GetCurrentTransactionId(); - } - START_CRIT_SECTION(); MarkBufferDirty(buf); @@ -578,7 +419,6 @@ fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum) XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT); xlrec.node = rel->rd_node; - xlrec.created = true; XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec)); XLogRegisterData((char *) tuple->t_data, tuple->t_len); @@ -958,28 +798,10 @@ nextval_internal(Oid relid, bool check_permissions) * It's sufficient to ensure the toplevel transaction has an xid, no need * to assign xids subxacts, that'll already trigger an appropriate wait. * (Have to do that here, so we're outside the critical section) - * - * We have to ensure we have a proper XID, which will be included in - * the XLOG record by XLogRecordAssemble. Otherwise the first nextval() - * in a subxact (without any preceding changes) would get XID 0, and it - * would then be impossible to decide which top xact it belongs to. - * It'd also trigger assert in DecodeSequence. We only do that with - * wal_level=logical, though. - * - * XXX This might seem unnecessary, because if there's no XID the xact - * couldn't have done anything important yet, e.g. it could not have - * created a sequence. But that's incorrect, because of subxacts. The - * current subtransaction might not have done anything yet (thus no XID), - * but an earlier one might have created the sequence. */ if (logit && RelationNeedsWAL(seqrel)) - { GetTopTransactionId(); - if (XLogLogicalInfoActive()) - GetCurrentTransactionId(); - } - /* ready to change the on-disk (or really, in-buffer) tuple */ START_CRIT_SECTION(); @@ -1015,7 +837,6 @@ nextval_internal(Oid relid, bool check_permissions) seq->log_cnt = 0; xlrec.node = seqrel->rd_node; - xlrec.created = false; XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec)); XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len); @@ -1181,13 +1002,8 @@ do_setval(Oid relid, int64 next, bool iscalled) /* check the comment above nextval_internal()'s equivalent call. */ if (RelationNeedsWAL(seqrel)) - { GetTopTransactionId(); - if (XLogLogicalInfoActive()) - GetCurrentTransactionId(); - } - /* ready to change the on-disk (or really, in-buffer) tuple */ START_CRIT_SECTION(); @@ -1208,8 +1024,6 @@ do_setval(Oid relid, int64 next, bool iscalled) XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT); xlrec.node = seqrel->rd_node; - xlrec.created = false; - XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec)); XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len); diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 057ab4b6a3f..2e8d8afead8 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -90,7 +90,6 @@ typedef struct SubOpts } SubOpts; static List *fetch_table_list(WalReceiverConn *wrconn, List *publications); -static List *fetch_sequence_list(WalReceiverConn *wrconn, List *publications); static void check_duplicates_in_publist(List *publist, Datum *datums); static List *merge_publications(List *oldpublist, List *newpublist, bool addpub, const char *subname); static void ReportSlotConnectionError(List *rstates, Oid subid, char *slotname, char *err); @@ -639,9 +638,9 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, { char *err; WalReceiverConn *wrconn; - List *relations; + List *tables; ListCell *lc; - char sync_state; + char table_state; /* Try to connect to the publisher. */ wrconn = walrcv_connect(conninfo, true, stmt->subname, &err); @@ -658,17 +657,14 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, * Set sync state based on if we were asked to do data copy or * not. */ - sync_state = opts.copy_data ? SUBREL_STATE_INIT : SUBREL_STATE_READY; + table_state = opts.copy_data ? SUBREL_STATE_INIT : SUBREL_STATE_READY; /* - * Get the table and sequence list from publisher and build - * local relation sync status info. + * Get the table list from publisher and build local table status + * info. */ - relations = fetch_table_list(wrconn, publications); - relations = list_concat(relations, - fetch_sequence_list(wrconn, publications)); - - foreach(lc, relations) + tables = fetch_table_list(wrconn, publications); + foreach(lc, tables) { RangeVar *rv = (RangeVar *) lfirst(lc); Oid relid; @@ -679,7 +675,7 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, CheckSubscriptionRelkind(get_rel_relkind(relid), rv->schemaname, rv->relname); - AddSubscriptionRelState(subid, relid, sync_state, + AddSubscriptionRelState(subid, relid, table_state, InvalidXLogRecPtr); } @@ -705,12 +701,12 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, * * Note that if tables were specified but copy_data is false * then it is safe to enable two_phase up-front because those - * relations are already initially in READY state. When the - * subscription has no relations, we leave the twophase state - * as PENDING, to allow ALTER SUBSCRIPTION ... REFRESH + * tables are already initially in READY state. When the + * subscription has no tables, we leave the twophase state as + * PENDING, to allow ALTER SUBSCRIPTION ... REFRESH * PUBLICATION to work. */ - if (opts.twophase && !opts.copy_data && relations != NIL) + if (opts.twophase && !opts.copy_data && tables != NIL) twophase_enabled = true; walrcv_create_slot(wrconn, opts.slot_name, false, twophase_enabled, @@ -786,10 +782,8 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data, if (validate_publications) check_publications(wrconn, validate_publications); - /* Get the list of relations from publisher. */ + /* Get the table list from publisher. */ pubrel_names = fetch_table_list(wrconn, sub->publications); - pubrel_names = list_concat(pubrel_names, - fetch_sequence_list(wrconn, sub->publications)); /* Get local table list. */ subrel_states = GetSubscriptionRelations(sub->oid); @@ -1814,75 +1808,6 @@ fetch_table_list(WalReceiverConn *wrconn, List *publications) } /* - * Get the list of sequences which belong to specified publications on the - * publisher connection. - */ -static List * -fetch_sequence_list(WalReceiverConn *wrconn, List *publications) -{ - WalRcvExecResult *res; - StringInfoData cmd; - TupleTableSlot *slot; - Oid tableRow[2] = {TEXTOID, TEXTOID}; - ListCell *lc; - bool first; - List *tablelist = NIL; - - Assert(list_length(publications) > 0); - - initStringInfo(&cmd); - appendStringInfoString(&cmd, "SELECT DISTINCT s.schemaname, s.sequencename\n" - " FROM pg_catalog.pg_publication_sequences s\n" - " WHERE s.pubname IN ("); - first = true; - foreach(lc, publications) - { - char *pubname = strVal(lfirst(lc)); - - if (first) - first = false; - else - appendStringInfoString(&cmd, ", "); - - appendStringInfoString(&cmd, quote_literal_cstr(pubname)); - } - appendStringInfoChar(&cmd, ')'); - - res = walrcv_exec(wrconn, cmd.data, 2, tableRow); - pfree(cmd.data); - - if (res->status != WALRCV_OK_TUPLES) - ereport(ERROR, - (errmsg("could not receive list of replicated sequences from the publisher: %s", - res->err))); - - /* Process sequences. */ - slot = MakeSingleTupleTableSlot(res->tupledesc, &TTSOpsMinimalTuple); - while (tuplestore_gettupleslot(res->tuplestore, true, false, slot)) - { - char *nspname; - char *relname; - bool isnull; - RangeVar *rv; - - nspname = TextDatumGetCString(slot_getattr(slot, 1, &isnull)); - Assert(!isnull); - relname = TextDatumGetCString(slot_getattr(slot, 2, &isnull)); - Assert(!isnull); - - rv = makeRangeVar(nspname, relname, -1); - tablelist = lappend(tablelist, rv); - - ExecClearTuple(slot); - } - ExecDropSingleTupleTableSlot(slot); - - walrcv_clear_result(res); - - return tablelist; -} - -/* * This is to report the connection failure while dropping replication slots. * Here, we report the WARNING for all tablesync slots so that user can drop * them manually, if required. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 4dd545cdd20..90edd0bb97d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -42,7 +42,6 @@ #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" -#include "catalog/pg_publication_namespace.h" #include "catalog/pg_statistic_ext.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_trigger.h" @@ -16409,14 +16408,11 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema) * Check that setting the relation to a different schema won't result in a * publication having both a schema and the same schema's table, as this * is not supported. - * - * XXX We do this for tables and sequences, but it's better to keep the two - * blocks separate, to make the strings easier to translate. */ if (stmt->objectType == OBJECT_TABLE) { ListCell *lc; - List *schemaPubids = GetSchemaPublications(nspOid, PUB_OBJTYPE_TABLE); + List *schemaPubids = GetSchemaPublications(nspOid); List *relPubids = GetRelationPublications(RelationGetRelid(rel)); foreach(lc, relPubids) @@ -16434,27 +16430,6 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema) get_publication_name(pubid, false))); } } - else if (stmt->objectType == OBJECT_SEQUENCE) - { - ListCell *lc; - List *schemaPubids = GetSchemaPublications(nspOid, PUB_OBJTYPE_SEQUENCE); - List *relPubids = GetRelationPublications(RelationGetRelid(rel)); - - foreach(lc, relPubids) - { - Oid pubid = lfirst_oid(lc); - - if (list_member_oid(schemaPubids, pubid)) - ereport(ERROR, - errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot move sequence \"%s\" to schema \"%s\"", - RelationGetRelationName(rel), stmt->newschema), - errdetail("The schema \"%s\" and same schema's sequence \"%s\" cannot be part of the same publication \"%s\".", - stmt->newschema, - RelationGetRelationName(rel), - get_publication_name(pubid, false))); - } - } /* common checks on switching namespaces */ CheckSetNamespace(oldNspOid, nspOid); diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 228e3547012..27989bd723d 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -649,9 +649,7 @@ void CheckSubscriptionRelkind(char relkind, const char *nspname, const char *relname) { - if (relkind != RELKIND_RELATION && - relkind != RELKIND_PARTITIONED_TABLE && - relkind != RELKIND_SEQUENCE) + if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot use relation \"%s.%s\" as logical replication target", diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 46a1943d97a..1585cf2d58c 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -5390,7 +5390,7 @@ _copyCreatePublicationStmt(const CreatePublicationStmt *from) COPY_STRING_FIELD(pubname); COPY_NODE_FIELD(options); COPY_NODE_FIELD(pubobjects); - COPY_NODE_FIELD(for_all_objects); + COPY_SCALAR_FIELD(for_all_tables); return newnode; } @@ -5403,7 +5403,7 @@ _copyAlterPublicationStmt(const AlterPublicationStmt *from) COPY_STRING_FIELD(pubname); COPY_NODE_FIELD(options); COPY_NODE_FIELD(pubobjects); - COPY_NODE_FIELD(for_all_objects); + COPY_SCALAR_FIELD(for_all_tables); COPY_SCALAR_FIELD(action); return newnode; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 1f765f42c91..caad20e0478 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -2688,7 +2688,7 @@ _equalCreatePublicationStmt(const CreatePublicationStmt *a, COMPARE_STRING_FIELD(pubname); COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(pubobjects); - COMPARE_NODE_FIELD(for_all_objects); + COMPARE_SCALAR_FIELD(for_all_tables); return true; } @@ -2700,7 +2700,7 @@ _equalAlterPublicationStmt(const AlterPublicationStmt *a, COMPARE_STRING_FIELD(pubname); COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(pubobjects); - COMPARE_NODE_FIELD(for_all_objects); + COMPARE_SCALAR_FIELD(for_all_tables); COMPARE_SCALAR_FIELD(action); return true; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 2cc92a89432..c9941d9cb4f 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 pub_obj_type_list + drop_option_list pub_obj_list %type <node> opt_routine_body %type <groupclause> group_clause @@ -588,7 +588,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <node> var_value zone_value %type <rolespec> auth_ident RoleSpec opt_granted_by %type <publicationobjectspec> PublicationObjSpec -%type <node> pub_obj_type %type <keyword> unreserved_keyword type_func_name_keyword %type <keyword> col_name_keyword reserved_keyword @@ -9863,10 +9862,13 @@ 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: + * + * TABLE table [, ...] + * ALL TABLES IN SCHEMA schema [, ...] + * *****************************************************************************/ CreatePublicationStmt: @@ -9877,12 +9879,12 @@ CreatePublicationStmt: n->options = $4; $$ = (Node *)n; } - | CREATE PUBLICATION name FOR ALL pub_obj_type_list opt_definition + | CREATE PUBLICATION name FOR ALL TABLES opt_definition { CreatePublicationStmt *n = makeNode(CreatePublicationStmt); n->pubname = $3; n->options = $7; - n->for_all_objects = $6; + n->for_all_tables = true; $$ = (Node *)n; } | CREATE PUBLICATION name FOR pub_obj_list opt_definition @@ -9932,26 +9934,6 @@ PublicationObjSpec: $$->pubobjtype = PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA; $$->location = @5; } - | SEQUENCE relation_expr - { - $$ = makeNode(PublicationObjSpec); - $$->pubobjtype = PUBLICATIONOBJ_SEQUENCE; - $$->pubtable = makeNode(PublicationTable); - $$->pubtable->relation = $2; - } - | ALL SEQUENCES IN_P SCHEMA ColId - { - $$ = makeNode(PublicationObjSpec); - $$->pubobjtype = PUBLICATIONOBJ_SEQUENCES_IN_SCHEMA; - $$->name = $5; - $$->location = @5; - } - | ALL SEQUENCES IN_P SCHEMA CURRENT_SCHEMA - { - $$ = makeNode(PublicationObjSpec); - $$->pubobjtype = PUBLICATIONOBJ_SEQUENCES_IN_CUR_SCHEMA; - $$->location = @5; - } | ColId opt_column_list OptWhereClause { $$ = makeNode(PublicationObjSpec); @@ -10013,19 +9995,6 @@ 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 ) @@ -10036,6 +10005,11 @@ pub_obj_type_list: pub_obj_type * * ALTER PUBLICATION name SET pub_obj [, ...] * + * pub_obj is one of: + * + * TABLE table_name [, ...] + * ALL TABLES IN SCHEMA schema_name [, ...] + * *****************************************************************************/ AlterPublicationStmt: @@ -18757,8 +18731,7 @@ preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner) if (pubobj->pubobjtype == PUBLICATIONOBJ_CONTINUATION) pubobj->pubobjtype = prevobjtype; - if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLE || - pubobj->pubobjtype == PUBLICATIONOBJ_SEQUENCE) + if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLE) { /* relation name or pubtable must be set for this type of object */ if (!pubobj->name && !pubobj->pubtable) @@ -18809,30 +18782,6 @@ preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner) errmsg("invalid schema name at or near"), parser_errposition(pubobj->location)); } - else if (pubobj->pubobjtype == PUBLICATIONOBJ_SEQUENCES_IN_SCHEMA || - pubobj->pubobjtype == PUBLICATIONOBJ_SEQUENCES_IN_CUR_SCHEMA) - { - /* WHERE clause is not allowed on a schema object */ - if (pubobj->pubtable && pubobj->pubtable->whereClause) - ereport(ERROR, - errcode(ERRCODE_SYNTAX_ERROR), - errmsg("WHERE clause not allowed for schema"), - parser_errposition(pubobj->location)); - - /* - * We can distinguish between the different type of schema - * objects based on whether name and pubtable is set. - */ - if (pubobj->name) - pubobj->pubobjtype = PUBLICATIONOBJ_SEQUENCES_IN_SCHEMA; - else if (!pubobj->name && !pubobj->pubtable) - pubobj->pubobjtype = PUBLICATIONOBJ_SEQUENCES_IN_CUR_SCHEMA; - else - ereport(ERROR, - errcode(ERRCODE_SYNTAX_ERROR), - errmsg("invalid schema name at or near"), - parser_errposition(pubobj->location)); - } prevobjtype = pubobj->pubobjtype; } diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c index c6ea7c98e15..6303647fe0f 100644 --- a/src/backend/replication/logical/decode.c +++ b/src/backend/replication/logical/decode.c @@ -42,7 +42,6 @@ #include "replication/reorderbuffer.h" #include "replication/snapbuild.h" #include "storage/standby.h" -#include "commands/sequence.h" /* individual record(group)'s handlers */ static void DecodeInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); @@ -64,7 +63,6 @@ static void DecodePrepare(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, /* common function to decode tuples */ static void DecodeXLogTuple(char *data, Size len, ReorderBufferTupleBuf *tup); -static void DecodeSeqTuple(char *data, Size len, ReorderBufferTupleBuf *tuple); /* helper functions for decoding transactions */ static inline bool FilterPrepare(LogicalDecodingContext *ctx, @@ -1252,132 +1250,3 @@ DecodeTXNNeedSkip(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, (txn_dbid != InvalidOid && txn_dbid != ctx->slot->data.database) || ctx->fast_forward || FilterByOrigin(ctx, origin_id)); } - -/* - * DecodeSeqTuple - * decode tuple describing the sequence increment - * - * Sequences are represented as a table with a single row, which gets updated - * by nextval(). The tuple is stored in WAL right after the xl_seq_rec, so we - * simply copy it into the tuplebuf (similar to seq_redo). - */ -static void -DecodeSeqTuple(char *data, Size len, ReorderBufferTupleBuf *tuple) -{ - int datalen = len - sizeof(xl_seq_rec) - SizeofHeapTupleHeader; - - Assert(datalen >= 0); - - tuple->tuple.t_len = datalen + SizeofHeapTupleHeader; - - ItemPointerSetInvalid(&tuple->tuple.t_self); - - tuple->tuple.t_tableOid = InvalidOid; - - memcpy(((char *) tuple->tuple.t_data), - data + sizeof(xl_seq_rec), - SizeofHeapTupleHeader); - - memcpy(((char *) tuple->tuple.t_data) + SizeofHeapTupleHeader, - data + sizeof(xl_seq_rec) + SizeofHeapTupleHeader, - datalen); -} - -/* - * Handle sequence decode - * - * Decoding sequences is a bit tricky, because while most sequence actions - * are non-transactional (not subject to rollback), some need to be handled - * as transactional. - * - * By default, a sequence increment is non-transactional - we must not queue - * it in a transaction as other changes, because the transaction might get - * rolled back and we'd discard the increment. The downstream would not be - * notified about the increment, which is wrong. - * - * On the other hand, the sequence may be created in a transaction. In this - * case we *should* queue the change as other changes in the transaction, - * because we don't want to send the increments for unknown sequence to the - * plugin - it might get confused about which sequence it's related to etc. - */ -void -sequence_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) -{ - SnapBuild *builder = ctx->snapshot_builder; - ReorderBufferTupleBuf *tuplebuf; - RelFileNode target_node; - XLogReaderState *r = buf->record; - char *tupledata = NULL; - Size tuplelen; - Size datalen = 0; - TransactionId xid = XLogRecGetXid(r); - uint8 info = XLogRecGetInfo(buf->record) & ~XLR_INFO_MASK; - xl_seq_rec *xlrec; - Snapshot snapshot; - RepOriginId origin_id = XLogRecGetOrigin(r); - bool transactional; - - /* only decode changes flagged with XLOG_SEQ_LOG */ - if (info != XLOG_SEQ_LOG) - elog(ERROR, "unexpected RM_SEQ_ID record type: %u", info); - - ReorderBufferProcessXid(ctx->reorder, XLogRecGetXid(r), buf->origptr); - - /* - * If we don't have snapshot or we are just fast-forwarding, there is no - * point in decoding messages. - */ - if (SnapBuildCurrentState(builder) < SNAPBUILD_FULL_SNAPSHOT || - ctx->fast_forward) - return; - - /* only interested in our database */ - XLogRecGetBlockTag(r, 0, &target_node, NULL, NULL); - if (target_node.dbNode != ctx->slot->data.database) - return; - - /* output plugin doesn't look for this origin, no need to queue */ - if (FilterByOrigin(ctx, XLogRecGetOrigin(r))) - return; - - tupledata = XLogRecGetData(r); - datalen = XLogRecGetDataLen(r); - tuplelen = datalen - SizeOfHeapHeader - sizeof(xl_seq_rec); - - /* extract the WAL record, with "created" flag */ - xlrec = (xl_seq_rec *) XLogRecGetData(r); - - /* XXX how could we have sequence change without data? */ - if(!datalen || !tupledata) - return; - - tuplebuf = ReorderBufferGetTupleBuf(ctx->reorder, tuplelen); - DecodeSeqTuple(tupledata, datalen, tuplebuf); - - /* - * Should we handle the sequence increment as transactional or not? - * - * If the sequence was created in a still-running transaction, treat - * it as transactional and queue the increments. Otherwise it needs - * to be treated as non-transactional, in which case we send it to - * the plugin right away. - */ - transactional = ReorderBufferSequenceIsTransactional(ctx->reorder, - target_node, - xlrec->created); - - /* Skip the change if already processed (per the snapshot). */ - if (transactional && - !SnapBuildProcessChange(builder, xid, buf->origptr)) - return; - else if (!transactional && - (SnapBuildCurrentState(builder) != SNAPBUILD_CONSISTENT || - SnapBuildXactNeedsSkip(builder, buf->origptr))) - return; - - /* Queue the increment (or send immediately if not transactional). */ - snapshot = SnapBuildGetOrBuildSnapshot(builder, xid); - ReorderBufferQueueSequence(ctx->reorder, xid, snapshot, buf->endptr, - origin_id, target_node, transactional, - xlrec->created, tuplebuf); -} diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c index 30e33dace33..788769dd738 100644 --- a/src/backend/replication/logical/logical.c +++ b/src/backend/replication/logical/logical.c @@ -73,10 +73,6 @@ static void truncate_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, static void message_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, XLogRecPtr message_lsn, bool transactional, const char *prefix, Size message_size, const char *message); -static void sequence_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, - XLogRecPtr sequence_lsn, Relation rel, - bool transactional, - int64 last_value, int64 log_cnt, bool is_called); /* streaming callbacks */ static void stream_start_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, @@ -94,10 +90,6 @@ static void stream_change_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn static void stream_message_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, XLogRecPtr message_lsn, bool transactional, const char *prefix, Size message_size, const char *message); -static void stream_sequence_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, - XLogRecPtr sequence_lsn, Relation rel, - bool transactional, - int64 last_value, int64 log_cnt, bool is_called); static void stream_truncate_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, int nrelations, Relation relations[], ReorderBufferChange *change); @@ -226,7 +218,6 @@ StartupDecodingContext(List *output_plugin_options, ctx->reorder->apply_truncate = truncate_cb_wrapper; ctx->reorder->commit = commit_cb_wrapper; ctx->reorder->message = message_cb_wrapper; - ctx->reorder->sequence = sequence_cb_wrapper; /* * To support streaming, we require start/stop/abort/commit/change @@ -243,7 +234,6 @@ StartupDecodingContext(List *output_plugin_options, (ctx->callbacks.stream_commit_cb != NULL) || (ctx->callbacks.stream_change_cb != NULL) || (ctx->callbacks.stream_message_cb != NULL) || - (ctx->callbacks.stream_sequence_cb != NULL) || (ctx->callbacks.stream_truncate_cb != NULL); /* @@ -261,7 +251,6 @@ StartupDecodingContext(List *output_plugin_options, ctx->reorder->stream_commit = stream_commit_cb_wrapper; ctx->reorder->stream_change = stream_change_cb_wrapper; ctx->reorder->stream_message = stream_message_cb_wrapper; - ctx->reorder->stream_sequence = stream_sequence_cb_wrapper; ctx->reorder->stream_truncate = stream_truncate_cb_wrapper; @@ -1217,42 +1206,6 @@ message_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, } static void -sequence_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, - XLogRecPtr sequence_lsn, Relation rel, bool transactional, - int64 last_value, int64 log_cnt, bool is_called) -{ - LogicalDecodingContext *ctx = cache->private_data; - LogicalErrorCallbackState state; - ErrorContextCallback errcallback; - - Assert(!ctx->fast_forward); - - if (ctx->callbacks.sequence_cb == NULL) - return; - - /* Push callback + info on the error context stack */ - state.ctx = ctx; - state.callback_name = "sequence"; - state.report_location = sequence_lsn; - errcallback.callback = output_plugin_error_callback; - errcallback.arg = (void *) &state; - errcallback.previous = error_context_stack; - error_context_stack = &errcallback; - - /* set output state */ - ctx->accept_writes = true; - ctx->write_xid = txn != NULL ? txn->xid : InvalidTransactionId; - ctx->write_location = sequence_lsn; - - /* do the actual work: call callback */ - ctx->callbacks.sequence_cb(ctx, txn, sequence_lsn, rel, transactional, - last_value, log_cnt, is_called); - - /* Pop the error context stack */ - error_context_stack = errcallback.previous; -} - -static void stream_start_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, XLogRecPtr first_lsn) { @@ -1558,47 +1511,6 @@ stream_message_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, } static void -stream_sequence_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, - XLogRecPtr sequence_lsn, Relation rel, - bool transactional, - int64 last_value, int64 log_cnt, bool is_called) -{ - LogicalDecodingContext *ctx = cache->private_data; - LogicalErrorCallbackState state; - ErrorContextCallback errcallback; - - Assert(!ctx->fast_forward); - - /* We're only supposed to call this when streaming is supported. */ - Assert(ctx->streaming); - - /* this callback is optional */ - if (ctx->callbacks.stream_sequence_cb == NULL) - return; - - /* Push callback + info on the error context stack */ - state.ctx = ctx; - state.callback_name = "stream_sequence"; - state.report_location = sequence_lsn; - errcallback.callback = output_plugin_error_callback; - errcallback.arg = (void *) &state; - errcallback.previous = error_context_stack; - error_context_stack = &errcallback; - - /* set output state */ - ctx->accept_writes = true; - ctx->write_xid = txn != NULL ? txn->xid : InvalidTransactionId; - ctx->write_location = sequence_lsn; - - /* do the actual work: call callback */ - ctx->callbacks.sequence_cb(ctx, txn, sequence_lsn, rel, transactional, - last_value, log_cnt, is_called); - - /* Pop the error context stack */ - error_context_stack = errcallback.previous; -} - -static void stream_truncate_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, int nrelations, Relation relations[], ReorderBufferChange *change) diff --git a/src/backend/replication/logical/proto.c b/src/backend/replication/logical/proto.c index 18d3cbb9248..ff8513e2d29 100644 --- a/src/backend/replication/logical/proto.c +++ b/src/backend/replication/logical/proto.c @@ -663,56 +663,6 @@ logicalrep_write_message(StringInfo out, TransactionId xid, XLogRecPtr lsn, } /* - * Write SEQUENCE to stream - */ -void -logicalrep_write_sequence(StringInfo out, Relation rel, TransactionId xid, - XLogRecPtr lsn, bool transactional, - int64 last_value, int64 log_cnt, bool is_called) -{ - uint8 flags = 0; - char *relname; - - pq_sendbyte(out, LOGICAL_REP_MSG_SEQUENCE); - - /* transaction ID (if not valid, we're not streaming) */ - if (TransactionIdIsValid(xid)) - pq_sendint32(out, xid); - - pq_sendint8(out, flags); - pq_sendint64(out, lsn); - - logicalrep_write_namespace(out, RelationGetNamespace(rel)); - relname = RelationGetRelationName(rel); - pq_sendstring(out, relname); - - pq_sendint8(out, transactional); - pq_sendint64(out, last_value); - pq_sendint64(out, log_cnt); - pq_sendint8(out, is_called); -} - -/* - * Read SEQUENCE from the stream. - */ -void -logicalrep_read_sequence(StringInfo in, LogicalRepSequence *seqdata) -{ - /* XXX skipping flags and lsn */ - pq_getmsgint(in, 1); - pq_getmsgint64(in); - - /* Read relation name from stream */ - seqdata->nspname = pstrdup(logicalrep_read_namespace(in)); - seqdata->seqname = pstrdup(pq_getmsgstring(in)); - - seqdata->transactional = pq_getmsgint(in, 1); - seqdata->last_value = pq_getmsgint64(in); - seqdata->log_cnt = pq_getmsgint64(in); - seqdata->is_called = pq_getmsgint(in, 1); -} - -/* * Write relation description to the output stream. */ void @@ -1286,8 +1236,6 @@ logicalrep_message_type(LogicalRepMsgType action) return "STREAM ABORT"; case LOGICAL_REP_MSG_STREAM_PREPARE: return "STREAM PREPARE"; - case LOGICAL_REP_MSG_SEQUENCE: - return "SEQUENCE"; } elog(ERROR, "invalid logical replication message type \"%c\"", action); diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 4702750a2e7..5adc016d449 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -77,40 +77,6 @@ * a bit more memory to the oldest subtransactions, because it's likely * they are the source for the next sequence of changes. * - * When decoding sequences, we differentiate between a sequences created - * in a (running) transaction, and sequences created in other (already - * committed) transactions. Changes for sequences created in the same - * top-level transaction are treated as "transactional" i.e. just like - * any other change from that transaction (and discarded in case of a - * rollback). Changes for sequences created earlier are treated as not - * transactional - are processed immediately, as if performed outside - * any transaction (and thus not rolled back). - * - * This mixed behavior is necessary - sequences are non-transactional - * (e.g. ROLLBACK does not undo the sequence increments). But for new - * sequences, we need to handle them in a transactional way, because if - * we ever get some DDL support, the sequence won't exist until the - * transaction gets applied. So we need to ensure the increments don't - * happen until the sequence gets created. - * - * To differentiate which sequences are "old" and which were created - * in a still-running transaction, we track sequences created in running - * transactions in a hash table. Sequences are identified by relfilenode, - * and we track XID of the (sub)transaction that created it. This means - * that if a transaction does something that changes the relfilenode - * (like an alter / reset of a sequence), the new relfilenode will be - * treated as if created in the transaction. The list of sequences gets - * discarded when the transaction completes (commit/rollback). - * - * We don't use the XID to check if it's the same top-level transaction. - * It's enough to know it was created in an in-progress transaction, - * and we know it must be the current one because otherwise it wouldn't - * see the sequence object. - * - * The XID may be valid even for non-transactional sequences - we simply - * keep the XID logged to WAL, it's up to the reorderbuffer to decide if - * the increment is transactional. - * * ------------------------------------------------------------------------- */ #include "postgres.h" @@ -125,7 +91,6 @@ #include "access/xact.h" #include "access/xlog_internal.h" #include "catalog/catalog.h" -#include "commands/sequence.h" #include "lib/binaryheap.h" #include "miscadmin.h" #include "pgstat.h" @@ -151,13 +116,6 @@ typedef struct ReorderBufferTXNByIdEnt ReorderBufferTXN *txn; } ReorderBufferTXNByIdEnt; -/* entry for hash table we use to track sequences created in running xacts */ -typedef struct ReorderBufferSequenceEnt -{ - RelFileNode rnode; - TransactionId xid; -} ReorderBufferSequenceEnt; - /* data structures for (relfilenode, ctid) => (cmin, cmax) mapping */ typedef struct ReorderBufferTupleCidKey { @@ -388,14 +346,6 @@ ReorderBufferAllocate(void) buffer->by_txn = hash_create("ReorderBufferByXid", 1000, &hash_ctl, HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); - /* hash table of sequences, mapping relfilenode to XID of transaction */ - hash_ctl.keysize = sizeof(RelFileNode); - hash_ctl.entrysize = sizeof(ReorderBufferSequenceEnt); - hash_ctl.hcxt = buffer->context; - - buffer->sequences = hash_create("ReorderBufferSequenceHash", 1000, &hash_ctl, - HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); - buffer->by_txn_last_xid = InvalidTransactionId; buffer->by_txn_last_txn = NULL; @@ -582,13 +532,6 @@ ReorderBufferReturnChange(ReorderBuffer *rb, ReorderBufferChange *change, change->data.truncate.relids = NULL; } break; - case REORDER_BUFFER_CHANGE_SEQUENCE: - if (change->data.sequence.tuple) - { - ReorderBufferReturnTupleBuf(rb, change->data.sequence.tuple); - change->data.sequence.tuple = NULL; - } - break; case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: @@ -924,230 +867,6 @@ ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid, } /* - * Treat the sequence increment as transactional? - * - * The hash table tracks all sequences created in in-progress transactions, - * so we simply do a lookup (the sequence is identified by relfilende). If - * we find a match, the increment should be handled as transactional. - */ -bool -ReorderBufferSequenceIsTransactional(ReorderBuffer *rb, - RelFileNode rnode, bool created) -{ - bool found = false; - - if (created) - return true; - - hash_search(rb->sequences, - (void *) &rnode, - HASH_FIND, - &found); - - return found; -} - -/* - * Cleanup sequences created in in-progress transactions. - * - * There's no way to search by XID, so we simply do a seqscan of all - * the entries in the hash table. Hopefully there are only a couple - * entries in most cases - people generally don't create many new - * sequences over and over. - */ -static void -ReorderBufferSequenceCleanup(ReorderBuffer *rb, TransactionId xid) -{ - HASH_SEQ_STATUS scan_status; - ReorderBufferSequenceEnt *ent; - - hash_seq_init(&scan_status, rb->sequences); - while ((ent = (ReorderBufferSequenceEnt *) hash_seq_search(&scan_status)) != NULL) - { - /* skip sequences not from this transaction */ - if (ent->xid != xid) - continue; - - (void) hash_search(rb->sequences, - (void *) &(ent->rnode), - HASH_REMOVE, NULL); - } -} - -/* - * A transactional sequence increment is queued to be processed upon commit - * and a non-transactional increment gets processed immediately. - * - * A sequence update may be both transactional and non-transactional. When - * created in a running transaction, treat it as transactional and queue - * the change in it. Otherwise treat it as non-transactional, so that we - * don't forget the increment in case of a rollback. - */ -void -ReorderBufferQueueSequence(ReorderBuffer *rb, TransactionId xid, - Snapshot snapshot, XLogRecPtr lsn, RepOriginId origin_id, - RelFileNode rnode, bool transactional, bool created, - ReorderBufferTupleBuf *tuplebuf) -{ - /* - * Change needs to be handled as transactional, because the sequence was - * created in a transaction that is still running. In that case all the - * changes need to be queued in that transaction, we must not send them - * to the downstream until the transaction commits. - * - * There's a bit of a trouble with subtransactions - we can't queue it - * into the subxact, because it might be rolled back and we'd lose the - * increment. We need to queue it into the same (sub)xact that created - * the sequence, which is why we track the XID in the hash table. - */ - if (transactional) - { - MemoryContext oldcontext; - ReorderBufferChange *change; - - /* lookup sequence by relfilenode */ - ReorderBufferSequenceEnt *ent; - bool found; - - /* transactional changes require a transaction */ - Assert(xid != InvalidTransactionId); - - /* search the lookup table (we ignore the return value, found is enough) */ - ent = hash_search(rb->sequences, - (void *) &rnode, - created ? HASH_ENTER : HASH_FIND, - &found); - - /* - * If this is the "create" increment, we must not have found any - * pre-existing entry in the hash table (i.e. there must not be - * any conflicting sequence). - */ - Assert(!(created && found)); - - /* But we must have either created or found an existing entry. */ - Assert(created || found); - - /* - * When creating the sequence, remember the XID of the transaction - * that created id. - */ - if (created) - ent->xid = xid; - - /* XXX Maybe check that we're still in the same top-level xact? */ - - /* OK, allocate and queue the change */ - oldcontext = MemoryContextSwitchTo(rb->context); - - change = ReorderBufferGetChange(rb); - - change->action = REORDER_BUFFER_CHANGE_SEQUENCE; - change->origin_id = origin_id; - - memcpy(&change->data.sequence.relnode, &rnode, sizeof(RelFileNode)); - - change->data.sequence.tuple = tuplebuf; - - /* add it to the same subxact that created the sequence */ - ReorderBufferQueueChange(rb, ent->xid, lsn, change, false); - - MemoryContextSwitchTo(oldcontext); - } - else - { - /* - * This increment is for a sequence that was not created in any - * running transaction, so we treat it as non-transactional and - * just send it to the output plugin directly. - */ - ReorderBufferTXN *txn = NULL; - volatile Snapshot snapshot_now = snapshot; - bool using_subtxn; - -#ifdef USE_ASSERT_CHECKING - /* All "creates" have to be handled as transactional. */ - Assert(!created); - - /* Make sure the sequence is not in the hash table. */ - { - bool found; - hash_search(rb->sequences, - (void *) &rnode, - HASH_FIND, &found); - Assert(!found); - } -#endif - - if (xid != InvalidTransactionId) - txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, true); - - /* setup snapshot to allow catalog access */ - SetupHistoricSnapshot(snapshot_now, NULL); - - /* - * Decoding needs access to syscaches et al., which in turn use - * heavyweight locks and such. Thus we need to have enough state around to - * keep track of those. The easiest way is to simply use a transaction - * internally. That also allows us to easily enforce that nothing writes - * to the database by checking for xid assignments. - * - * When we're called via the SQL SRF there's already a transaction - * started, so start an explicit subtransaction there. - */ - using_subtxn = IsTransactionOrTransactionBlock(); - - PG_TRY(); - { - Relation relation; - HeapTuple tuple; - Form_pg_sequence_data seq; - Oid reloid; - - if (using_subtxn) - BeginInternalSubTransaction("sequence"); - else - StartTransactionCommand(); - - reloid = RelidByRelfilenode(rnode.spcNode, rnode.relNode); - - if (reloid == InvalidOid) - elog(ERROR, "could not map filenode \"%s\" to relation OID", - relpathperm(rnode, - MAIN_FORKNUM)); - - relation = RelationIdGetRelation(reloid); - tuple = &tuplebuf->tuple; - seq = (Form_pg_sequence_data) GETSTRUCT(tuple); - - rb->sequence(rb, txn, lsn, relation, transactional, - seq->last_value, seq->log_cnt, seq->is_called); - - RelationClose(relation); - - TeardownHistoricSnapshot(false); - - AbortCurrentTransaction(); - - if (using_subtxn) - RollbackAndReleaseCurrentSubTransaction(); - } - PG_CATCH(); - { - TeardownHistoricSnapshot(true); - - AbortCurrentTransaction(); - - if (using_subtxn) - RollbackAndReleaseCurrentSubTransaction(); - - PG_RE_THROW(); - } - PG_END_TRY(); - } -} - -/* * AssertTXNLsnOrder * Verify LSN ordering of transaction lists in the reorderbuffer * @@ -1823,9 +1542,6 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) &found); Assert(found); - /* Remove sequences created in this transaction (if any). */ - ReorderBufferSequenceCleanup(rb, txn->xid); - /* remove entries spilled to disk */ if (rbtxn_is_serialized(txn)) ReorderBufferRestoreCleanup(rb, txn); @@ -2242,29 +1958,6 @@ ReorderBufferApplyMessage(ReorderBuffer *rb, ReorderBufferTXN *txn, } /* - * Helper function for ReorderBufferProcessTXN for applying sequences. - */ -static inline void -ReorderBufferApplySequence(ReorderBuffer *rb, ReorderBufferTXN *txn, - Relation relation, ReorderBufferChange *change, - bool streaming) -{ - HeapTuple tuple; - Form_pg_sequence_data seq; - - tuple = &change->data.sequence.tuple->tuple; - seq = (Form_pg_sequence_data) GETSTRUCT(tuple); - - /* Only ever called from ReorderBufferApplySequence, so transational. */ - if (streaming) - rb->stream_sequence(rb, txn, change->lsn, relation, true, - seq->last_value, seq->log_cnt, seq->is_called); - else - rb->sequence(rb, txn, change->lsn, relation, true, - seq->last_value, seq->log_cnt, seq->is_called); -} - -/* * Function to store the command id and snapshot at the end of the current * stream so that we can reuse the same while sending the next stream. */ @@ -2706,31 +2399,6 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, case REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID: elog(ERROR, "tuplecid value in changequeue"); break; - - case REORDER_BUFFER_CHANGE_SEQUENCE: - Assert(snapshot_now); - - reloid = RelidByRelfilenode(change->data.sequence.relnode.spcNode, - change->data.sequence.relnode.relNode); - - if (reloid == InvalidOid) - elog(ERROR, "could not map filenode \"%s\" to relation OID", - relpathperm(change->data.sequence.relnode, - MAIN_FORKNUM)); - - relation = RelationIdGetRelation(reloid); - - if (!RelationIsValid(relation)) - elog(ERROR, "could not open relation with OID %u (for filenode \"%s\")", - reloid, - relpathperm(change->data.sequence.relnode, - MAIN_FORKNUM)); - - if (RelationIsLogicallyLogged(relation)) - ReorderBufferApplySequence(rb, txn, relation, change, streaming); - - RelationClose(relation); - break; } } @@ -4117,39 +3785,6 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn, break; } - case REORDER_BUFFER_CHANGE_SEQUENCE: - { - char *data; - ReorderBufferTupleBuf *tup; - Size len = 0; - - tup = change->data.sequence.tuple; - - if (tup) - { - sz += sizeof(HeapTupleData); - len = tup->tuple.t_len; - sz += len; - } - - /* make sure we have enough space */ - ReorderBufferSerializeReserve(rb, sz); - - data = ((char *) rb->outbuf) + sizeof(ReorderBufferDiskChange); - /* might have been reallocated above */ - ondisk = (ReorderBufferDiskChange *) rb->outbuf; - - if (len) - { - memcpy(data, &tup->tuple, sizeof(HeapTupleData)); - data += sizeof(HeapTupleData); - - memcpy(data, tup->tuple.t_data, len); - data += len; - } - - break; - } case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: @@ -4414,22 +4049,6 @@ ReorderBufferChangeSize(ReorderBufferChange *change) break; } - case REORDER_BUFFER_CHANGE_SEQUENCE: - { - ReorderBufferTupleBuf *tup; - Size len = 0; - - tup = change->data.sequence.tuple; - - if (tup) - { - sz += sizeof(HeapTupleData); - len = tup->tuple.t_len; - sz += len; - } - - break; - } case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: @@ -4729,30 +4348,6 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn, break; } - - case REORDER_BUFFER_CHANGE_SEQUENCE: - if (change->data.sequence.tuple) - { - uint32 tuplelen = ((HeapTuple) data)->t_len; - - change->data.sequence.tuple = - ReorderBufferGetTupleBuf(rb, tuplelen - SizeofHeapTupleHeader); - - /* restore ->tuple */ - memcpy(&change->data.sequence.tuple->tuple, data, - sizeof(HeapTupleData)); - data += sizeof(HeapTupleData); - - /* reset t_data pointer into the new tuplebuf */ - change->data.sequence.tuple->tuple.t_data = - ReorderBufferTupleBufData(change->data.sequence.tuple); - - /* restore tuple data itself */ - memcpy(change->data.sequence.tuple->tuple.t_data, data, tuplelen); - data += tuplelen; - } - break; - case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c index b2cb31eaad7..49ceec3bdc8 100644 --- a/src/backend/replication/logical/tablesync.c +++ b/src/backend/replication/logical/tablesync.c @@ -100,7 +100,6 @@ #include "catalog/pg_subscription_rel.h" #include "catalog/pg_type.h" #include "commands/copy.h" -#include "commands/sequence.h" #include "miscadmin.h" #include "parser/parse_relation.h" #include "pgstat.h" @@ -1138,95 +1137,6 @@ copy_table(Relation rel) } /* - * Fetch sequence data (current state) from the remote node. - */ -static void -fetch_sequence_data(char *nspname, char *relname, - int64 *last_value, int64 *log_cnt, bool *is_called) -{ - WalRcvExecResult *res; - StringInfoData cmd; - TupleTableSlot *slot; - Oid tableRow[3] = {INT8OID, INT8OID, BOOLOID}; - - initStringInfo(&cmd); - appendStringInfo(&cmd, "SELECT last_value, log_cnt, is_called\n" - " FROM %s", quote_qualified_identifier(nspname, relname)); - - res = walrcv_exec(LogRepWorkerWalRcvConn, cmd.data, 3, tableRow); - pfree(cmd.data); - - if (res->status != WALRCV_OK_TUPLES) - ereport(ERROR, - (errmsg("could not receive list of replicated tables from the publisher: %s", - res->err))); - - /* Process the sequence. */ - slot = MakeSingleTupleTableSlot(res->tupledesc, &TTSOpsMinimalTuple); - while (tuplestore_gettupleslot(res->tuplestore, true, false, slot)) - { - bool isnull; - - *last_value = DatumGetInt64(slot_getattr(slot, 1, &isnull)); - Assert(!isnull); - - *log_cnt = DatumGetInt64(slot_getattr(slot, 2, &isnull)); - Assert(!isnull); - - *is_called = DatumGetBool(slot_getattr(slot, 3, &isnull)); - Assert(!isnull); - - ExecClearTuple(slot); - } - ExecDropSingleTupleTableSlot(slot); - - walrcv_clear_result(res); -} - -/* - * Copy existing data of a sequence from publisher. - * - * Caller is responsible for locking the local relation. - */ -static void -copy_sequence(Relation rel) -{ - LogicalRepRelMapEntry *relmapentry; - LogicalRepRelation lrel; - List *qual = NIL; - StringInfoData cmd; - int64 last_value = 0, - log_cnt = 0; - bool is_called = 0; - - /* Get the publisher relation info. */ - fetch_remote_table_info(get_namespace_name(RelationGetNamespace(rel)), - RelationGetRelationName(rel), &lrel, &qual); - - /* sequences don't have row filters */ - Assert(!qual); - - /* Put the relation into relmap. */ - logicalrep_relmap_update(&lrel); - - /* Map the publisher relation to local one. */ - relmapentry = logicalrep_rel_open(lrel.remoteid, NoLock); - Assert(rel == relmapentry->localrel); - - /* Start copy on the publisher. */ - initStringInfo(&cmd); - - Assert(lrel.relkind == RELKIND_SEQUENCE); - - fetch_sequence_data(lrel.nspname, lrel.relname, &last_value, &log_cnt, &is_called); - - /* tablesync sets the sequences in non-transactional way */ - SetSequence(RelationGetRelid(rel), false, last_value, log_cnt, is_called); - - logicalrep_rel_close(relmapentry, NoLock); -} - -/* * Determine the tablesync slot name. * * The name must not exceed NAMEDATALEN - 1 because of remote node constraints @@ -1487,21 +1397,10 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos) originname))); } - /* Do the right action depending on the relation kind. */ - if (get_rel_relkind(RelationGetRelid(rel)) == RELKIND_SEQUENCE) - { - /* Now do the initial sequence copy */ - PushActiveSnapshot(GetTransactionSnapshot()); - copy_sequence(rel); - PopActiveSnapshot(); - } - else - { - /* Now do the initial data copy */ - PushActiveSnapshot(GetTransactionSnapshot()); - copy_table(rel); - PopActiveSnapshot(); - } + /* Now do the initial data copy */ + PushActiveSnapshot(GetTransactionSnapshot()); + copy_table(rel); + PopActiveSnapshot(); res = walrcv_exec(LogRepWorkerWalRcvConn, "COMMIT", 0, NULL); if (res->status != WALRCV_OK_COMMAND) diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 7ade49652e7..9181d3e8636 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -143,7 +143,6 @@ #include "catalog/pg_subscription.h" #include "catalog/pg_subscription_rel.h" #include "catalog/pg_tablespace.h" -#include "commands/sequence.h" #include "commands/tablecmds.h" #include "commands/tablespace.h" #include "commands/trigger.h" @@ -1145,57 +1144,6 @@ apply_handle_origin(StringInfo s) } /* - * Handle SEQUENCE message. - */ -static void -apply_handle_sequence(StringInfo s) -{ - LogicalRepSequence seq; - Oid relid; - - if (handle_streamed_transaction(LOGICAL_REP_MSG_SEQUENCE, s)) - return; - - logicalrep_read_sequence(s, &seq); - - /* - * Non-transactional sequence updates should not be part of a remote - * transaction. There should not be any running transaction. - */ - Assert((!seq.transactional) || in_remote_transaction); - Assert(!(!seq.transactional && in_remote_transaction)); - Assert(!(!seq.transactional && IsTransactionState())); - - /* - * Make sure we're in a transaction (needed by SetSequence). For - * non-transactional updates we're guaranteed to start a new one, - * and we'll commit it at the end. - */ - if (!IsTransactionState()) - { - StartTransactionCommand(); - maybe_reread_subscription(); - } - - relid = RangeVarGetRelid(makeRangeVar(seq.nspname, - seq.seqname, -1), - RowExclusiveLock, false); - - /* lock the sequence in AccessExclusiveLock, as expected by SetSequence */ - LockRelationOid(relid, AccessExclusiveLock); - - /* apply the sequence change */ - SetSequence(relid, seq.transactional, seq.last_value, seq.log_cnt, seq.is_called); - - /* - * Commit the per-stream transaction (we only do this when not in - * remote transaction, i.e. for non-transactional sequence updates. - */ - if (!in_remote_transaction) - CommitTransactionCommand(); -} - -/* * Handle STREAM START message. */ static void @@ -2563,10 +2511,6 @@ apply_dispatch(StringInfo s) */ break; - case LOGICAL_REP_MSG_SEQUENCE: - apply_handle_sequence(s); - return; - case LOGICAL_REP_MSG_STREAM_START: apply_handle_stream_start(s); break; diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 9d33630464c..fe5accca576 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -15,7 +15,6 @@ #include "access/tupconvert.h" #include "catalog/partition.h" #include "catalog/pg_publication.h" -#include "catalog/pg_publication_namespace.h" #include "catalog/pg_publication_rel.h" #include "commands/defrem.h" #include "executor/executor.h" @@ -55,10 +54,6 @@ static void pgoutput_message(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr message_lsn, bool transactional, const char *prefix, Size sz, const char *message); -static void pgoutput_sequence(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, XLogRecPtr sequence_lsn, - Relation relation, bool transactional, - int64 last_value, int64 log_cnt, bool is_called); static bool pgoutput_origin_filter(LogicalDecodingContext *ctx, RepOriginId origin_id); static void pgoutput_begin_prepare_txn(LogicalDecodingContext *ctx, @@ -260,7 +255,6 @@ _PG_output_plugin_init(OutputPluginCallbacks *cb) cb->change_cb = pgoutput_change; cb->truncate_cb = pgoutput_truncate; cb->message_cb = pgoutput_message; - cb->sequence_cb = pgoutput_sequence; cb->commit_cb = pgoutput_commit_txn; cb->begin_prepare_cb = pgoutput_begin_prepare_txn; @@ -277,7 +271,6 @@ _PG_output_plugin_init(OutputPluginCallbacks *cb) cb->stream_commit_cb = pgoutput_stream_commit; cb->stream_change_cb = pgoutput_change; cb->stream_message_cb = pgoutput_message; - cb->stream_sequence_cb = pgoutput_sequence; cb->stream_truncate_cb = pgoutput_truncate; /* transaction streaming - two-phase commit */ cb->stream_prepare_cb = pgoutput_stream_prepare_txn; @@ -291,7 +284,6 @@ parse_output_parameters(List *options, PGOutputData *data) bool publication_names_given = false; bool binary_option_given = false; bool messages_option_given = false; - bool sequences_option_given = false; bool streaming_given = false; bool two_phase_option_given = false; @@ -299,7 +291,6 @@ parse_output_parameters(List *options, PGOutputData *data) data->streaming = false; data->messages = false; data->two_phase = false; - data->sequences = true; foreach(lc, options) { @@ -368,16 +359,6 @@ parse_output_parameters(List *options, PGOutputData *data) data->messages = defGetBoolean(defel); } - else if (strcmp(defel->defname, "sequences") == 0) - { - if (sequences_option_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); - sequences_option_given = true; - - data->sequences = defGetBoolean(defel); - } else if (strcmp(defel->defname, "streaming") == 0) { if (streaming_given) @@ -1709,64 +1690,6 @@ pgoutput_message(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, OutputPluginWrite(ctx, true); } -static void -pgoutput_sequence(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, XLogRecPtr sequence_lsn, - Relation relation, bool transactional, - int64 last_value, int64 log_cnt, bool is_called) -{ - PGOutputData *data = (PGOutputData *) ctx->output_plugin_private; - TransactionId xid = InvalidTransactionId; - RelationSyncEntry *relentry; - - if (!data->sequences) - return; - - if (!is_publishable_relation(relation)) - return; - - /* - * Remember the xid for the message in streaming mode. See - * pgoutput_change. - */ - if (in_streaming) - xid = txn->xid; - - relentry = get_rel_sync_entry(data, relation); - - /* - * First check the sequence filter. - * - * We handle just REORDER_BUFFER_CHANGE_SEQUENCE here. - */ - if (!relentry->pubactions.pubsequence) - return; - - /* - * Output BEGIN if we haven't yet. Avoid for non-transactional - * sequence changes. - */ - if (transactional) - { - PGOutputTxnData *txndata = (PGOutputTxnData *) txn->output_plugin_private; - - /* Send BEGIN if we haven't yet */ - if (txndata && !txndata->sent_begin_txn) - pgoutput_send_begin(ctx, txn); - } - - OutputPluginPrepareWrite(ctx, true); - logicalrep_write_sequence(ctx->out, - relation, - xid, - sequence_lsn, - transactional, - last_value, - log_cnt, - is_called); - OutputPluginWrite(ctx, true); -} - /* * Currently we always forward. */ @@ -2052,8 +1975,7 @@ get_rel_sync_entry(PGOutputData *data, Relation relation) entry->schema_sent = false; entry->streamed_txns = NIL; entry->pubactions.pubinsert = entry->pubactions.pubupdate = - entry->pubactions.pubdelete = entry->pubactions.pubtruncate = - entry->pubactions.pubsequence = false; + entry->pubactions.pubdelete = entry->pubactions.pubtruncate = false; entry->new_slot = NULL; entry->old_slot = NULL; memset(entry->exprstate, 0, sizeof(entry->exprstate)); @@ -2068,18 +1990,18 @@ get_rel_sync_entry(PGOutputData *data, Relation relation) { Oid schemaId = get_rel_namespace(relid); List *pubids = GetRelationPublications(relid); - char relkind = get_rel_relkind(relid); - char objectType = pub_get_object_type_for_relkind(relkind); + /* * We don't acquire a lock on the namespace system table as we build * the cache entry using a historic snapshot and all the later changes * are absorbed while decoding WAL. */ - List *schemaPubids = GetSchemaPublications(schemaId, objectType); + List *schemaPubids = GetSchemaPublications(schemaId); ListCell *lc; Oid publish_as_relid = relid; int publish_ancestor_level = 0; bool am_partition = get_rel_relispartition(relid); + char relkind = get_rel_relkind(relid); List *rel_publications = NIL; /* Reload publications if needed before use. */ @@ -2111,7 +2033,6 @@ get_rel_sync_entry(PGOutputData *data, Relation relation) entry->pubactions.pubupdate = false; entry->pubactions.pubdelete = false; entry->pubactions.pubtruncate = false; - entry->pubactions.pubsequence = false; /* * Tuple slots cleanups. (Will be rebuilt later if needed). @@ -2159,11 +2080,9 @@ get_rel_sync_entry(PGOutputData *data, Relation relation) /* * If this is a FOR ALL TABLES publication, pick the partition root - * and set the ancestor level accordingly. If this is a FOR ALL - * SEQUENCES publication, we publish it too but we don't need to - * pick the partition root etc. + * and set the ancestor level accordingly. */ - if (pub->alltables || pub->allsequences) + if (pub->alltables) { publish = true; if (pub->pubviaroot && am_partition) @@ -2227,7 +2146,6 @@ get_rel_sync_entry(PGOutputData *data, Relation relation) entry->pubactions.pubupdate |= pub->pubactions.pubupdate; entry->pubactions.pubdelete |= pub->pubactions.pubdelete; entry->pubactions.pubtruncate |= pub->pubactions.pubtruncate; - entry->pubactions.pubsequence |= pub->pubactions.pubsequence; /* * We want to publish the changes as the top-most ancestor diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 1f29670a131..43f14c233d6 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -56,7 +56,6 @@ #include "catalog/pg_opclass.h" #include "catalog/pg_proc.h" #include "catalog/pg_publication.h" -#include "catalog/pg_publication_namespace.h" #include "catalog/pg_rewrite.h" #include "catalog/pg_shseclabel.h" #include "catalog/pg_statistic_ext.h" @@ -5568,8 +5567,6 @@ RelationBuildPublicationDesc(Relation relation, PublicationDesc *pubdesc) Oid schemaid; List *ancestors = NIL; Oid relid = RelationGetRelid(relation); - char relkind = relation->rd_rel->relkind; - char objType; /* * If not publishable, it publishes no actions. (pgoutput_change() will @@ -5600,15 +5597,8 @@ RelationBuildPublicationDesc(Relation relation, PublicationDesc *pubdesc) /* Fetch the publication membership info. */ puboids = GetRelationPublications(relid); schemaid = RelationGetNamespace(relation); - objType = pub_get_object_type_for_relkind(relkind); + puboids = list_concat_unique_oid(puboids, GetSchemaPublications(schemaid)); - puboids = list_concat_unique_oid(puboids, - GetSchemaPublications(schemaid, objType)); - - /* - * If this is a partion (and thus a table), lookup all ancestors and track - * all publications them too. - */ if (relation->rd_rel->relispartition) { /* Add publications that the ancestors are in too. */ @@ -5620,23 +5610,12 @@ RelationBuildPublicationDesc(Relation relation, PublicationDesc *pubdesc) puboids = list_concat_unique_oid(puboids, GetRelationPublications(ancestor)); - - /* include all publications publishing schema of all ancestors */ schemaid = get_rel_namespace(ancestor); puboids = list_concat_unique_oid(puboids, - GetSchemaPublications(schemaid, - PUB_OBJTYPE_TABLE)); + GetSchemaPublications(schemaid)); } } - - /* - * Consider also FOR ALL TABLES and FOR ALL SEQUENCES publications, - * depending on the relkind of the relation. - */ - if (relation->rd_rel->relkind == RELKIND_SEQUENCE) - puboids = list_concat_unique_oid(puboids, GetAllSequencesPublications()); - else - puboids = list_concat_unique_oid(puboids, GetAllTablesPublications()); + puboids = list_concat_unique_oid(puboids, GetAllTablesPublications()); foreach(lc, puboids) { @@ -5655,7 +5634,6 @@ RelationBuildPublicationDesc(Relation relation, PublicationDesc *pubdesc) pubdesc->pubactions.pubupdate |= pubform->pubupdate; pubdesc->pubactions.pubdelete |= pubform->pubdelete; pubdesc->pubactions.pubtruncate |= pubform->pubtruncate; - pubdesc->pubactions.pubsequence |= pubform->pubsequence; /* * Check if all columns referenced in the filter expression are part of diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 8d265f2d23c..1912b121463 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -653,12 +653,12 @@ static const struct cachedesc cacheinfo[] = { 64 }, {PublicationNamespaceRelationId, /* PUBLICATIONNAMESPACEMAP */ - PublicationNamespacePnnspidPnpubidPntypeIndexId, - 3, + PublicationNamespacePnnspidPnpubidIndexId, + 2, { Anum_pg_publication_namespace_pnnspid, Anum_pg_publication_namespace_pnpubid, - Anum_pg_publication_namespace_pntype, + 0, 0 }, 64 diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 3c2201a725f..196f6d23a3e 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -3814,12 +3814,10 @@ 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; int i_pubtruncate; - int i_pubsequence; int i_pubviaroot; int i, ntups; @@ -3835,29 +3833,23 @@ getPublications(Archive *fout, int *numPublications) resetPQExpBuffer(query); /* Get the publications. */ - if (fout->remoteVersion >= 150000) - appendPQExpBuffer(query, - "SELECT p.tableoid, p.oid, p.pubname, " - "p.pubowner, " - "p.puballtables, p.puballsequences, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubsequence, p.pubviaroot " - "FROM pg_publication p"); - else if (fout->remoteVersion >= 130000) + if (fout->remoteVersion >= 130000) appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, p.pubname, " "p.pubowner, " - "p.puballtables, false AS puballsequences, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubsequence, p.pubviaroot " + "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot " "FROM pg_publication p"); else if (fout->remoteVersion >= 110000) appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, p.pubname, " "p.pubowner, " - "p.puballtables, false AS puballsequences, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubsequence, false AS pubviaroot " + "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot " "FROM pg_publication p"); else appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, p.pubname, " "p.pubowner, " - "p.puballtables, false AS puballsequences, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubsequence, false AS pubviaroot " + "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot " "FROM pg_publication p"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -3869,12 +3861,10 @@ 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"); i_pubtruncate = PQfnumber(res, "pubtruncate"); - i_pubsequence = PQfnumber(res, "pubsequence"); i_pubviaroot = PQfnumber(res, "pubviaroot"); pubinfo = pg_malloc(ntups * sizeof(PublicationInfo)); @@ -3890,8 +3880,6 @@ 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 = @@ -3900,8 +3888,6 @@ getPublications(Archive *fout, int *numPublications) (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0); pubinfo[i].pubtruncate = (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0); - pubinfo[i].pubsequence = - (strcmp(PQgetvalue(res, i, i_pubsequence), "t") == 0); pubinfo[i].pubviaroot = (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0); @@ -3947,9 +3933,6 @@ 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) { @@ -3984,15 +3967,6 @@ dumpPublication(Archive *fout, const PublicationInfo *pubinfo) first = false; } - if (pubinfo->pubsequence) - { - if (!first) - appendPQExpBufferStr(query, ", "); - - appendPQExpBufferStr(query, "sequence"); - first = false; - } - appendPQExpBufferStr(query, "'"); if (pubinfo->pubviaroot) @@ -4039,7 +4013,6 @@ getPublicationNamespaces(Archive *fout) int i_oid; int i_pnpubid; int i_pnnspid; - int i_pntype; int i, j, ntups; @@ -4051,7 +4024,7 @@ getPublicationNamespaces(Archive *fout) /* Collect all publication membership info. */ appendPQExpBufferStr(query, - "SELECT tableoid, oid, pnpubid, pnnspid, pntype " + "SELECT tableoid, oid, pnpubid, pnnspid " "FROM pg_catalog.pg_publication_namespace"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -4061,7 +4034,6 @@ getPublicationNamespaces(Archive *fout) i_oid = PQfnumber(res, "oid"); i_pnpubid = PQfnumber(res, "pnpubid"); i_pnnspid = PQfnumber(res, "pnnspid"); - i_pntype = PQfnumber(res, "pntype"); /* this allocation may be more than we need */ pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo)); @@ -4071,7 +4043,6 @@ getPublicationNamespaces(Archive *fout) { Oid pnpubid = atooid(PQgetvalue(res, i, i_pnpubid)); Oid pnnspid = atooid(PQgetvalue(res, i, i_pnnspid)); - char pntype = PQgetvalue(res, i, i_pntype)[0]; PublicationInfo *pubinfo; NamespaceInfo *nspinfo; @@ -4103,7 +4074,6 @@ getPublicationNamespaces(Archive *fout) pubsinfo[j].dobj.name = nspinfo->dobj.name; pubsinfo[j].publication = pubinfo; pubsinfo[j].pubschema = nspinfo; - pubsinfo[j].pubtype = pntype; /* Decide whether we want to dump it */ selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout); @@ -4269,11 +4239,7 @@ dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo) query = createPQExpBuffer(); appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name)); - - if (pubsinfo->pubtype == 't') - appendPQExpBuffer(query, "ADD ALL TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name)); - else - appendPQExpBuffer(query, "ADD ALL SEQUENCES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name)); + appendPQExpBuffer(query, "ADD ALL TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name)); /* * There is no point in creating drop query as the drop is done by schema @@ -4306,7 +4272,6 @@ dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo) TableInfo *tbinfo = pubrinfo->pubtable; PQExpBuffer query; char *tag; - char *description; /* Do nothing in data-only dump */ if (dopt->dataOnly) @@ -4316,19 +4281,8 @@ dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo) query = createPQExpBuffer(); - if (tbinfo->relkind == RELKIND_SEQUENCE) - { - appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD SEQUENCE", - fmtId(pubinfo->dobj.name)); - description = "PUBLICATION SEQUENCE"; - } - else - { - appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY", - fmtId(pubinfo->dobj.name)); - description = "PUBLICATION TABLE"; - } - + appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY", + fmtId(pubinfo->dobj.name)); appendPQExpBuffer(query, " %s", fmtQualifiedDumpable(tbinfo)); @@ -4357,7 +4311,7 @@ dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo) ARCHIVE_OPTS(.tag = tag, .namespace = tbinfo->dobj.namespace->dobj.name, .owner = pubinfo->rolname, - .description = description, + .description = "PUBLICATION TABLE", .section = SECTION_POST_DATA, .createStmt = query->data)); diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 688093c55e0..1d21c2906f1 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -615,12 +615,10 @@ typedef struct _PublicationInfo DumpableObject dobj; const char *rolname; bool puballtables; - bool puballsequences; bool pubinsert; bool pubupdate; bool pubdelete; bool pubtruncate; - bool pubsequence; bool pubviaroot; } PublicationInfo; @@ -646,7 +644,6 @@ typedef struct _PublicationSchemaInfo DumpableObject dobj; PublicationInfo *publication; NamespaceInfo *pubschema; - char pubtype; } PublicationSchemaInfo; /* diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index 75b754a4202..c65c92bfb0e 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -2420,7 +2420,7 @@ my %tests = ( create_order => 50, create_sql => 'CREATE PUBLICATION pub1;', regexp => qr/^ - \QCREATE PUBLICATION pub1 WITH (publish = 'insert, update, delete, truncate, sequence');\E + \QCREATE PUBLICATION pub1 WITH (publish = 'insert, update, delete, truncate');\E /xm, like => { %full_runs, section_post_data => 1, }, }, @@ -2440,27 +2440,16 @@ my %tests = ( create_order => 50, create_sql => 'CREATE PUBLICATION pub3;', regexp => qr/^ - \QCREATE PUBLICATION pub3 WITH (publish = 'insert, update, delete, truncate, sequence');\E + \QCREATE PUBLICATION pub3 WITH (publish = 'insert, update, delete, truncate');\E /xm, like => { %full_runs, section_post_data => 1, }, }, 'CREATE PUBLICATION pub4' => { create_order => 50, - create_sql => 'CREATE PUBLICATION pub4 - FOR ALL SEQUENCES - WITH (publish = \'\');', + create_sql => 'CREATE PUBLICATION pub4;', regexp => qr/^ - \QCREATE PUBLICATION pub4 FOR ALL SEQUENCES WITH (publish = '');\E - /xm, - like => { %full_runs, section_post_data => 1, }, - }, - - 'CREATE PUBLICATION pub5' => { - create_order => 50, - create_sql => 'CREATE PUBLICATION pub5;', - regexp => qr/^ - \QCREATE PUBLICATION pub5 WITH (publish = 'insert, update, delete, truncate, sequence');\E + \QCREATE PUBLICATION pub4 WITH (publish = 'insert, update, delete, truncate');\E /xm, like => { %full_runs, section_post_data => 1, }, }, @@ -2569,27 +2558,6 @@ my %tests = ( unlike => { exclude_dump_test_schema => 1, }, }, - 'ALTER PUBLICATION pub3 ADD ALL SEQUENCES IN SCHEMA dump_test' => { - create_order => 51, - create_sql => - 'ALTER PUBLICATION pub3 ADD ALL SEQUENCES IN SCHEMA dump_test;', - regexp => qr/^ - \QALTER PUBLICATION pub3 ADD ALL SEQUENCES IN SCHEMA dump_test;\E - /xm, - like => { %full_runs, section_post_data => 1, }, - unlike => { exclude_dump_test_schema => 1, }, - }, - - 'ALTER PUBLICATION pub3 ADD ALL SEQUENCES IN SCHEMA public' => { - create_order => 52, - create_sql => - 'ALTER PUBLICATION pub3 ADD ALL SEQUENCES IN SCHEMA public;', - regexp => qr/^ - \QALTER PUBLICATION pub3 ADD ALL SEQUENCES IN SCHEMA public;\E - /xm, - like => { %full_runs, section_post_data => 1, }, - }, - 'CREATE SCHEMA public' => { regexp => qr/^CREATE SCHEMA public;/m, diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 73bbbe2eb40..3f1b3802c22 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -1633,19 +1633,28 @@ 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),\n" - " seqstart,\n" - " seqmin,\n" - " seqmax,\n" - " seqincrement,\n" - " CASE WHEN seqcycle THEN '%s' ELSE '%s' END,\n" - " seqcache\n", + "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"), gettext_noop("yes"), - gettext_noop("no")); + gettext_noop("no"), + gettext_noop("Cycles?"), + gettext_noop("Cache")); appendPQExpBuffer(&buf, "FROM pg_catalog.pg_sequence\n" "WHERE seqrelid = '%s';", @@ -1654,15 +1663,22 @@ describeOneTableDetails(const char *schemaname, else { printfPQExpBuffer(&buf, - "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", + "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"), gettext_noop("yes"), - gettext_noop("no")); + gettext_noop("no"), + gettext_noop("Cycles?"), + gettext_noop("Cache")); appendPQExpBuffer(&buf, "FROM %s", fmtId(schemaname)); /* must be separate because fmtId isn't reentrant */ appendPQExpBuffer(&buf, ".%s;", fmtId(relationname)); @@ -1672,57 +1688,6 @@ 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) || '.' ||" @@ -1754,63 +1719,33 @@ describeOneTableDetails(const char *schemaname, switch (PQgetvalue(result, 0, 1)[0]) { case 'a': - printTableAddFooter(&cont, - psprintf(_("Owned by: %s"), - PQgetvalue(result, 0, 0))); + footers[0] = psprintf(_("Owned by: %s"), + PQgetvalue(result, 0, 0)); break; case 'i': - printTableAddFooter(&cont, - psprintf(_("Sequence for identity column: %s"), - PQgetvalue(result, 0, 0))); + footers[0] = psprintf(_("Sequence for identity column: %s"), + PQgetvalue(result, 0, 0)); break; } } PQclear(result); - /* print any publications */ - if (pset.sversion >= 150000) - { - int tuples = 0; - - printfPQExpBuffer(&buf, - "SELECT pubname\n" - "FROM pg_catalog.pg_publication p\n" - " JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n" - " JOIN pg_catalog.pg_class pc ON pc.relnamespace = pn.pnnspid\n" - "WHERE pc.oid ='%s' and pn.pntype = 's' and pg_catalog.pg_relation_is_publishable('%s')\n" - "UNION\n" - "SELECT pubname\n" - "FROM pg_catalog.pg_publication p\n" - " JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n" - "WHERE pr.prrelid = '%s'\n" - "UNION\n" - "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, oid, oid, oid); - - result = PSQLexec(buf.data); - if (!result) - goto error_return; - else - tuples = PQntuples(result); - - if (tuples > 0) - printTableAddFooter(&cont, _("Publications:")); + if (tableinfo.relpersistence == 'u') + printfPQExpBuffer(&title, _("Unlogged sequence \"%s.%s\""), + schemaname, relationname); + else + printfPQExpBuffer(&title, _("Sequence \"%s.%s\""), + schemaname, relationname); - /* Might be an empty set - that's ok */ - for (i = 0; i < tuples; i++) - { - printfPQExpBuffer(&buf, " \"%s\"", - PQgetvalue(result, i, 0)); + myopt.footers = footers; + myopt.topt.default_footer = false; + myopt.title = title.data; + myopt.translate_header = true; - printTableAddFooter(&cont, buf.data); - } - PQclear(result); - } + printQuery(res, &myopt, pset.queryFout, false, pset.logfile); - printTable(&cont, pset.queryFout, false, pset.logfile); + if (footers[0]) + free(footers[0]); retval = true; goto error_return; /* not an error, just return early */ @@ -2037,11 +1972,6 @@ 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++) { @@ -2968,7 +2898,7 @@ describeOneTableDetails(const char *schemaname, "FROM pg_catalog.pg_publication p\n" " JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n" " JOIN pg_catalog.pg_class pc ON pc.relnamespace = pn.pnnspid\n" - "WHERE pc.oid ='%s' and pn.pntype = 't' and pg_catalog.pg_relation_is_publishable('%s')\n" + "WHERE pc.oid ='%s' and pg_catalog.pg_relation_is_publishable('%s')\n" "UNION\n" "SELECT pubname\n" " , pg_get_expr(pr.prqual, c.oid)\n" @@ -4872,7 +4802,7 @@ listSchemas(const char *pattern, bool verbose, bool showSystem) int i; printfPQExpBuffer(&buf, - "SELECT pubname, (CASE WHEN pntype = 't' THEN 'tables' ELSE 'sequences' END) AS pubtype\n" + "SELECT pubname \n" "FROM pg_catalog.pg_publication p\n" " JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n" " JOIN pg_catalog.pg_namespace n ON n.oid = pn.pnnspid \n" @@ -4901,9 +4831,8 @@ listSchemas(const char *pattern, bool verbose, bool showSystem) /* Might be an empty set - that's ok */ for (i = 0; i < pub_schema_tuples; i++) { - printfPQExpBuffer(&buf, " \"%s\" (%s)", - PQgetvalue(result, i, 0), - PQgetvalue(result, i, 1)); + printfPQExpBuffer(&buf, " \"%s\"", + PQgetvalue(result, i, 0)); footers[i + 1] = pg_strdup(buf.data); } @@ -5908,7 +5837,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, false, false}; + static const bool translate_columns[] = {false, false, false, false, false, false, false, false}; if (pset.sversion < 100000) { @@ -5922,45 +5851,23 @@ listPublications(const char *pattern) initPQExpBuffer(&buf); - if (pset.sversion >= 150000) - 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")); - + 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\"", gettext_noop("Truncates")); - if (pset.sversion >= 150000) - appendPQExpBuffer(&buf, - ",\n pubsequence AS \"%s\"", - gettext_noop("Sequences")); if (pset.sversion >= 130000) appendPQExpBuffer(&buf, ",\n pubviaroot AS \"%s\"", @@ -6050,7 +5957,6 @@ describePublications(const char *pattern) PGresult *res; bool has_pubtruncate; bool has_pubviaroot; - bool has_pubsequence; PQExpBufferData title; printTableContent cont; @@ -6067,7 +5973,6 @@ describePublications(const char *pattern) has_pubtruncate = (pset.sversion >= 110000); has_pubviaroot = (pset.sversion >= 130000); - has_pubsequence = (pset.sversion >= 150000); initPQExpBuffer(&buf); @@ -6075,17 +5980,12 @@ describePublications(const char *pattern) "SELECT oid, pubname,\n" " pg_catalog.pg_get_userbyid(pubowner) AS owner,\n" " puballtables, pubinsert, pubupdate, pubdelete"); - if (has_pubtruncate) appendPQExpBufferStr(&buf, ", pubtruncate"); if (has_pubviaroot) appendPQExpBufferStr(&buf, ", pubviaroot"); - if (has_pubsequence) - appendPQExpBufferStr(&buf, - ", puballsequences, pubsequence"); - appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_publication\n"); @@ -6126,7 +6026,6 @@ describePublications(const char *pattern) char *pubid = PQgetvalue(res, i, 0); char *pubname = PQgetvalue(res, i, 1); bool puballtables = strcmp(PQgetvalue(res, i, 3), "t") == 0; - bool puballsequences = strcmp(PQgetvalue(res, i, 9), "t") == 0; printTableOpt myopt = pset.popt.topt; if (has_pubtruncate) @@ -6134,43 +6033,29 @@ describePublications(const char *pattern) if (has_pubviaroot) ncols++; - /* sequences have two extra columns (puballsequences, pubsequences) */ - if (has_pubsequence) - ncols += 2; - initPQExpBuffer(&title); printfPQExpBuffer(&title, _("Publication %s"), pubname); printTableInit(&cont, &myopt, title.data, ncols, nrows); 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); if (has_pubtruncate) printTableAddHeader(&cont, gettext_noop("Truncates"), true, align); - if (has_pubsequence) - printTableAddHeader(&cont, gettext_noop("Sequences"), true, align); if (has_pubviaroot) printTableAddHeader(&cont, gettext_noop("Via root"), true, align); - printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false); /* owner */ - printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false); /* all tables */ - - if (has_pubsequence) - printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false); /* all sequences */ - - printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false); /* insert */ - printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false); /* update */ - printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false); /* delete */ + printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false); + printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false); + printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false); + printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false); + printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false); if (has_pubtruncate) - printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false); /* truncate */ - if (has_pubsequence) - printTableAddCell(&cont, PQgetvalue(res, i, 10), false, false); /* sequence */ + printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false); if (has_pubviaroot) - printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false); /* via root */ + printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false); if (!puballtables) { @@ -6201,7 +6086,6 @@ describePublications(const char *pattern) "WHERE c.relnamespace = n.oid\n" " AND c.oid = pr.prrelid\n" " AND pr.prpubid = '%s'\n" - " AND c.relkind != 'S'\n" /* exclude sequences */ "ORDER BY 1,2", pubid); if (!addFooterToPublicationDesc(&buf, "Tables:", false, &cont)) goto error_return; @@ -6213,7 +6097,7 @@ describePublications(const char *pattern) "SELECT n.nspname\n" "FROM pg_catalog.pg_namespace n\n" " JOIN pg_catalog.pg_publication_namespace pn ON n.oid = pn.pnnspid\n" - "WHERE pn.pnpubid = '%s' AND pn.pntype = 't'\n" + "WHERE pn.pnpubid = '%s'\n" "ORDER BY 1", pubid); if (!addFooterToPublicationDesc(&buf, "Tables from schemas:", true, &cont)) @@ -6221,37 +6105,6 @@ describePublications(const char *pattern) } } - if (!puballsequences) - { - /* Get the sequences for the specified publication */ - printfPQExpBuffer(&buf, - "SELECT n.nspname, c.relname, NULL, NULL\n" - "FROM pg_catalog.pg_class c,\n" - " pg_catalog.pg_namespace n,\n" - " pg_catalog.pg_publication_rel pr\n" - "WHERE c.relnamespace = n.oid\n" - " AND c.oid = pr.prrelid\n" - " AND pr.prpubid = '%s'\n" - " AND c.relkind = 'S'\n" /* only sequences */ - "ORDER BY 1,2", pubid); - if (!addFooterToPublicationDesc(&buf, "Sequences:", false, &cont)) - goto error_return; - - if (pset.sversion >= 150000) - { - /* Get the schemas for the specified publication */ - printfPQExpBuffer(&buf, - "SELECT n.nspname\n" - "FROM pg_catalog.pg_namespace n\n" - " JOIN pg_catalog.pg_publication_namespace pn ON n.oid = pn.pnnspid\n" - "WHERE pn.pnpubid = '%s' AND pn.pntype = 's'\n" - "ORDER BY 1", pubid); - if (!addFooterToPublicationDesc(&buf, "Sequences from schemas:", - true, &cont)) - goto error_return; - } - } - printTable(&cont, pset.queryFout, false, pset.logfile); printTableCleanup(&cont); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 025d3f71a11..a2df39d0c1b 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -1827,15 +1827,11 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH("ADD", "DROP", "OWNER TO", "RENAME TO", "SET"); /* ALTER PUBLICATION <name> ADD */ else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD")) - COMPLETE_WITH("ALL TABLES IN SCHEMA", "ALL SEQUENCES IN SCHEMA", "TABLE", "SEQUENCE"); + COMPLETE_WITH("ALL TABLES IN SCHEMA", "TABLE"); else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE") || (HeadMatches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE") && ends_with(prev_wd, ','))) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables); - else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "SEQUENCE") || - (HeadMatches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "SEQUENCE") && - ends_with(prev_wd, ','))) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences); /* * "ALTER PUBLICATION <name> SET TABLE <name> WHERE (" - complete with * table attributes @@ -1854,11 +1850,11 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH(","); /* ALTER PUBLICATION <name> DROP */ else if (Matches("ALTER", "PUBLICATION", MatchAny, "DROP")) - COMPLETE_WITH("ALL TABLES IN SCHEMA", "ALL SEQUENCES IN SCHEMA", "TABLE", "SEQUENCE"); + COMPLETE_WITH("ALL TABLES IN SCHEMA", "TABLE"); /* ALTER PUBLICATION <name> SET */ else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET")) - COMPLETE_WITH("(", "ALL TABLES IN SCHEMA", "ALL SEQUENCES IN SCHEMA", "TABLE", "SEQUENCE"); - else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD|DROP|SET", "ALL", "TABLES|SEQUENCES", "IN", "SCHEMA")) + COMPLETE_WITH("(", "ALL TABLES IN SCHEMA", "TABLE"); + else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD|DROP|SET", "ALL", "TABLES", "IN", "SCHEMA")) COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas " AND nspname NOT LIKE E'pg\\\\_%%'", "CURRENT_SCHEMA"); @@ -2988,27 +2984,21 @@ 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 ALL TABLES IN SCHEMA", - "FOR SEQUENCE", "FOR ALL SEQUENCES", "FOR ALL SEQUENCES IN SCHEMA", - "WITH ("); + COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "FOR ALL TABLES IN SCHEMA", "WITH ("); else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR")) - COMPLETE_WITH("TABLE", "ALL TABLES", "ALL TABLES IN SCHEMA", - "SEQUENCE", "ALL SEQUENCES", "ALL SEQUENCES IN SCHEMA"); + COMPLETE_WITH("TABLE", "ALL TABLES", "ALL TABLES IN SCHEMA"); else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL")) - COMPLETE_WITH("TABLES", "TABLES IN SCHEMA", "SEQUENCES", "SEQUENCES IN SCHEMA"); - else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES|SEQUENCES")) + COMPLETE_WITH("TABLES", "TABLES IN SCHEMA"); + else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES")) COMPLETE_WITH("IN SCHEMA", "WITH ("); - else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE|SEQUENCE", MatchAny) && !ends_with(prev_wd, ',')) + else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE", MatchAny) && !ends_with(prev_wd, ',')) COMPLETE_WITH("WHERE (", "WITH ("); /* Complete "CREATE PUBLICATION <name> FOR TABLE" with "<table>, ..." */ else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables); - /* Complete "CREATE PUBLICATION <name> FOR SEQUENCE" with "<sequence>, ..." */ - else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "SEQUENCE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences); /* - * "CREATE PUBLICATION <name> FOR TABLE|SEQUENCE <name> WHERE (" - complete with + * "CREATE PUBLICATION <name> FOR TABLE <name> WHERE (" - complete with * table attributes */ else if (HeadMatches("CREATE", "PUBLICATION", MatchAny) && TailMatches("WHERE")) @@ -3019,14 +3009,14 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH(" WITH ("); /* - * Complete "CREATE PUBLICATION <name> FOR ALL TABLES|SEQUENCES IN SCHEMA <schema>, + * Complete "CREATE PUBLICATION <name> FOR ALL TABLES IN SCHEMA <schema>, * ..." */ - else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES|SEQUENCES", "IN", "SCHEMA")) + else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES", "IN", "SCHEMA")) COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas " AND nspname NOT LIKE E'pg\\\\_%%'", "CURRENT_SCHEMA"); - else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES|SEQUENCES", "IN", "SCHEMA", MatchAny) && (!ends_with(prev_wd, ','))) + else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES", "IN", "SCHEMA", MatchAny) && (!ends_with(prev_wd, ','))) COMPLETE_WITH("WITH ("); /* Complete "CREATE PUBLICATION <name> [...] WITH" */ else if (HeadMatches("CREATE", "PUBLICATION") && TailMatches("WITH", "(")) diff --git a/src/include/access/rmgrlist.h b/src/include/access/rmgrlist.h index cf8b6d48193..9a74721c97c 100644 --- a/src/include/access/rmgrlist.h +++ b/src/include/access/rmgrlist.h @@ -40,7 +40,7 @@ PG_RMGR(RM_BTREE_ID, "Btree", btree_redo, btree_desc, btree_identify, btree_xlog PG_RMGR(RM_HASH_ID, "Hash", hash_redo, hash_desc, hash_identify, NULL, NULL, hash_mask, NULL) PG_RMGR(RM_GIN_ID, "Gin", gin_redo, gin_desc, gin_identify, gin_xlog_startup, gin_xlog_cleanup, gin_mask, NULL) PG_RMGR(RM_GIST_ID, "Gist", gist_redo, gist_desc, gist_identify, gist_xlog_startup, gist_xlog_cleanup, gist_mask, NULL) -PG_RMGR(RM_SEQ_ID, "Sequence", seq_redo, seq_desc, seq_identify, NULL, NULL, seq_mask, sequence_decode) +PG_RMGR(RM_SEQ_ID, "Sequence", seq_redo, seq_desc, seq_identify, NULL, NULL, seq_mask, NULL) PG_RMGR(RM_SPGIST_ID, "SPGist", spg_redo, spg_desc, spg_identify, spg_xlog_startup, spg_xlog_cleanup, spg_mask, NULL) PG_RMGR(RM_BRIN_ID, "BRIN", brin_redo, brin_desc, brin_identify, NULL, NULL, brin_mask, NULL) PG_RMGR(RM_COMMIT_TS_ID, "CommitTs", commit_ts_redo, commit_ts_desc, commit_ts_identify, NULL, NULL, NULL, NULL) diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 67f3d8526cd..cec70caae1f 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202204074 +#define CATALOG_VERSION_NO 202204075 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 61876c4e808..52f56cf5b1b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11658,11 +11658,6 @@ provolatile => 's', prorettype => 'oid', proargtypes => 'text', proallargtypes => '{text,oid}', proargmodes => '{i,o}', proargnames => '{pubname,relid}', 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 186d8ea74b6..29b18566657 100644 --- a/src/include/catalog/pg_publication.h +++ b/src/include/catalog/pg_publication.h @@ -40,12 +40,6 @@ 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; @@ -58,9 +52,6 @@ CATALOG(pg_publication,6104,PublicationRelationId) /* true if truncates are published */ bool pubtruncate; - /* true if sequences are published */ - bool pubsequence; - /* true if partition changes are published using root schema */ bool pubviaroot; } FormData_pg_publication; @@ -81,7 +72,6 @@ typedef struct PublicationActions bool pubupdate; bool pubdelete; bool pubtruncate; - bool pubsequence; } PublicationActions; typedef struct PublicationDesc @@ -109,7 +99,6 @@ typedef struct Publication Oid oid; char *name; bool alltables; - bool allsequences; bool pubviaroot; PublicationActions pubactions; } Publication; @@ -141,16 +130,14 @@ typedef enum PublicationPartOpt PUBLICATION_PART_ALL, } PublicationPartOpt; -extern List *GetPublicationRelations(Oid pubid, char objectType, - PublicationPartOpt pub_partopt); +extern List *GetPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt); extern List *GetAllTablesPublications(void); extern List *GetAllTablesPublicationRelations(bool pubviaroot); -extern void GetActionsInPublication(Oid pubid, PublicationActions *actions); -extern List *GetPublicationSchemas(Oid pubid, char objectType); -extern List *GetSchemaPublications(Oid schemaid, char objectType); -extern List *GetSchemaPublicationRelations(Oid schemaid, char objectType, +extern List *GetPublicationSchemas(Oid pubid); +extern List *GetSchemaPublications(Oid schemaid); +extern List *GetSchemaPublicationRelations(Oid schemaid, PublicationPartOpt pub_partopt); -extern List *GetAllSchemaPublicationRelations(Oid puboid, char objectType, +extern List *GetAllSchemaPublicationRelations(Oid puboid, PublicationPartOpt pub_partopt); extern List *GetPubPartitionOptionRelations(List *result, PublicationPartOpt pub_partopt, @@ -158,15 +145,11 @@ extern List *GetPubPartitionOptionRelations(List *result, extern Oid GetTopMostAncestorInPublication(Oid puboid, List *ancestors, int *ancestor_level); -extern List *GetAllSequencesPublications(void); -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, bool if_not_exists); extern ObjectAddress publication_add_schema(Oid pubid, Oid schemaid, - char objectType, bool if_not_exists); extern Bitmapset *pub_collist_to_bitmapset(Bitmapset *columns, Datum pubcols, diff --git a/src/include/catalog/pg_publication_namespace.h b/src/include/catalog/pg_publication_namespace.h index 7340a1ec646..e4306da02e7 100644 --- a/src/include/catalog/pg_publication_namespace.h +++ b/src/include/catalog/pg_publication_namespace.h @@ -32,7 +32,6 @@ CATALOG(pg_publication_namespace,8901,PublicationNamespaceRelationId) Oid oid; /* oid */ Oid pnpubid BKI_LOOKUP(pg_publication); /* Oid of the publication */ Oid pnnspid BKI_LOOKUP(pg_namespace); /* Oid of the schema */ - char pntype; /* object type to include */ } FormData_pg_publication_namespace; /* ---------------- @@ -43,13 +42,6 @@ CATALOG(pg_publication_namespace,8901,PublicationNamespaceRelationId) typedef FormData_pg_publication_namespace *Form_pg_publication_namespace; DECLARE_UNIQUE_INDEX_PKEY(pg_publication_namespace_oid_index, 8902, PublicationNamespaceObjectIndexId, on pg_publication_namespace using btree(oid oid_ops)); -DECLARE_UNIQUE_INDEX(pg_publication_namespace_pnnspid_pnpubid_pntype_index, 8903, PublicationNamespacePnnspidPnpubidPntypeIndexId, on pg_publication_namespace using btree(pnnspid oid_ops, pnpubid oid_ops, pntype char_ops)); - -/* object type to include from a schema, maps to relkind */ -#define PUB_OBJTYPE_TABLE 't' /* table (regular or partitioned) */ -#define PUB_OBJTYPE_SEQUENCE 's' /* sequence object */ -#define PUB_OBJTYPE_UNSUPPORTED 'u' /* used for non-replicated types */ - -extern char pub_get_object_type_for_relkind(char relkind); +DECLARE_UNIQUE_INDEX(pg_publication_namespace_pnnspid_pnpubid_index, 8903, PublicationNamespacePnnspidPnpubidIndexId, on pg_publication_namespace using btree(pnnspid oid_ops, pnpubid oid_ops)); #endif /* PG_PUBLICATION_NAMESPACE_H */ diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h index f2381982d5d..9da23008101 100644 --- a/src/include/commands/sequence.h +++ b/src/include/commands/sequence.h @@ -48,7 +48,6 @@ typedef FormData_pg_sequence_data *Form_pg_sequence_data; typedef struct xl_seq_rec { RelFileNode node; - bool created; /* creates a new relfilenode (CREATE/ALTER) */ /* SEQUENCE TUPLE DATA FOLLOWS AT THE END */ } xl_seq_rec; @@ -61,7 +60,6 @@ extern ObjectAddress AlterSequence(ParseState *pstate, AlterSeqStmt *stmt); extern void SequenceChangePersistence(Oid relid, char newrelpersistence); extern void DeleteSequenceTuple(Oid relid); extern void ResetSequence(Oid seq_relid); -extern void SetSequence(Oid seq_relid, bool transactional, int64 last_value, int64 log_cnt, bool is_called); extern void ResetSequenceCaches(void); extern void seq_redo(XLogReaderState *rptr); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 8998d345605..1bdeb9eb3d3 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -4013,10 +4013,6 @@ typedef enum PublicationObjSpecType PUBLICATIONOBJ_TABLES_IN_SCHEMA, /* All tables in schema */ PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA, /* All tables in first element of * search_path */ - PUBLICATIONOBJ_SEQUENCE, /* Sequence type */ - PUBLICATIONOBJ_SEQUENCES_IN_SCHEMA, /* Sequences in schema type */ - PUBLICATIONOBJ_SEQUENCES_IN_CUR_SCHEMA, /* Get the first element of - * search_path */ PUBLICATIONOBJ_CONTINUATION /* Continuation of previous type */ } PublicationObjSpecType; @@ -4035,7 +4031,7 @@ typedef struct CreatePublicationStmt char *pubname; /* Name of the publication */ List *options; /* List of DefElem nodes */ List *pubobjects; /* Optional list of publication objects */ - List *for_all_objects; /* Special publication for all objects in db */ + bool for_all_tables; /* Special publication for all tables in db */ } CreatePublicationStmt; typedef enum AlterPublicationAction @@ -4058,7 +4054,7 @@ typedef struct AlterPublicationStmt * objects. */ List *pubobjects; /* Optional list of publication objects */ - List *for_all_objects; /* Special publication for all objects in db */ + bool for_all_tables; /* Special publication for all tables in db */ AlterPublicationAction action; /* What action to perform with the given * objects */ } AlterPublicationStmt; diff --git a/src/include/replication/decode.h b/src/include/replication/decode.h index 8e07bb7409a..a33c2a718a7 100644 --- a/src/include/replication/decode.h +++ b/src/include/replication/decode.h @@ -27,7 +27,6 @@ extern void heap2_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); extern void xact_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); extern void standby_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); extern void logicalmsg_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); -extern void sequence_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); extern void LogicalDecodingProcessRecord(LogicalDecodingContext *ctx, XLogReaderState *record); diff --git a/src/include/replication/logicalproto.h b/src/include/replication/logicalproto.h index 13ee10fdd4e..a771ab8ff33 100644 --- a/src/include/replication/logicalproto.h +++ b/src/include/replication/logicalproto.h @@ -61,7 +61,6 @@ typedef enum LogicalRepMsgType LOGICAL_REP_MSG_RELATION = 'R', LOGICAL_REP_MSG_TYPE = 'Y', LOGICAL_REP_MSG_MESSAGE = 'M', - LOGICAL_REP_MSG_SEQUENCE = 'Q', LOGICAL_REP_MSG_BEGIN_PREPARE = 'b', LOGICAL_REP_MSG_PREPARE = 'P', LOGICAL_REP_MSG_COMMIT_PREPARED = 'K', @@ -119,18 +118,6 @@ typedef struct LogicalRepTyp char *typname; /* name of the remote type */ } LogicalRepTyp; -/* Sequence info */ -typedef struct LogicalRepSequence -{ - Oid remoteid; /* unique id of the remote sequence */ - char *nspname; /* schema name of remote sequence */ - char *seqname; /* name of the remote sequence */ - bool transactional; - int64 last_value; - int64 log_cnt; - bool is_called; -} LogicalRepSequence; - /* Transaction info */ typedef struct LogicalRepBeginData { @@ -243,12 +230,6 @@ extern List *logicalrep_read_truncate(StringInfo in, bool *cascade, bool *restart_seqs); extern void logicalrep_write_message(StringInfo out, TransactionId xid, XLogRecPtr lsn, bool transactional, const char *prefix, Size sz, const char *message); -extern void logicalrep_write_sequence(StringInfo out, Relation rel, - TransactionId xid, XLogRecPtr lsn, - bool transactional, - int64 last_value, int64 log_cnt, - bool is_called); -extern void logicalrep_read_sequence(StringInfo in, LogicalRepSequence *seqdata); extern void logicalrep_write_rel(StringInfo out, TransactionId xid, Relation rel, Bitmapset *columns); extern LogicalRepRelation *logicalrep_read_rel(StringInfo in); diff --git a/src/include/replication/output_plugin.h b/src/include/replication/output_plugin.h index fe85d49a030..539dc8e6974 100644 --- a/src/include/replication/output_plugin.h +++ b/src/include/replication/output_plugin.h @@ -89,18 +89,6 @@ typedef void (*LogicalDecodeMessageCB) (struct LogicalDecodingContext *ctx, const char *message); /* - * Called for the generic logical decoding sequences. - */ -typedef void (*LogicalDecodeSequenceCB) (struct LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, - XLogRecPtr sequence_lsn, - Relation rel, - bool transactional, - int64 last_value, - int64 log_cnt, - bool is_called); - -/* * Filter changes by origin. */ typedef bool (*LogicalDecodeFilterByOriginCB) (struct LogicalDecodingContext *ctx, @@ -212,19 +200,6 @@ typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx const char *message); /* - * Called for the streaming generic logical decoding sequences from in-progress - * transactions. - */ -typedef void (*LogicalDecodeStreamSequenceCB) (struct LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, - XLogRecPtr sequence_lsn, - Relation rel, - bool transactional, - int64 last_value, - int64 log_cnt, - bool is_called); - -/* * Callback for streaming truncates from in-progress transactions. */ typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx, @@ -244,7 +219,6 @@ typedef struct OutputPluginCallbacks LogicalDecodeTruncateCB truncate_cb; LogicalDecodeCommitCB commit_cb; LogicalDecodeMessageCB message_cb; - LogicalDecodeSequenceCB sequence_cb; LogicalDecodeFilterByOriginCB filter_by_origin_cb; LogicalDecodeShutdownCB shutdown_cb; @@ -263,7 +237,6 @@ typedef struct OutputPluginCallbacks LogicalDecodeStreamCommitCB stream_commit_cb; LogicalDecodeStreamChangeCB stream_change_cb; LogicalDecodeStreamMessageCB stream_message_cb; - LogicalDecodeStreamSequenceCB stream_sequence_cb; LogicalDecodeStreamTruncateCB stream_truncate_cb; } OutputPluginCallbacks; diff --git a/src/include/replication/pgoutput.h b/src/include/replication/pgoutput.h index f4e9f35d09d..eafedd610a5 100644 --- a/src/include/replication/pgoutput.h +++ b/src/include/replication/pgoutput.h @@ -29,7 +29,6 @@ typedef struct PGOutputData bool streaming; bool messages; bool two_phase; - bool sequences; } PGOutputData; #endif /* PGOUTPUT_H */ diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index 0bcc150b331..f12e75d69be 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -64,8 +64,7 @@ typedef enum ReorderBufferChangeType REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT, REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM, REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT, - REORDER_BUFFER_CHANGE_TRUNCATE, - REORDER_BUFFER_CHANGE_SEQUENCE + REORDER_BUFFER_CHANGE_TRUNCATE } ReorderBufferChangeType; /* forward declaration */ @@ -159,13 +158,6 @@ typedef struct ReorderBufferChange uint32 ninvalidations; /* Number of messages */ SharedInvalidationMessage *invalidations; /* invalidation message */ } inval; - - /* Context data for Sequence changes */ - struct - { - RelFileNode relnode; - ReorderBufferTupleBuf *tuple; - } sequence; } data; /* @@ -438,15 +430,6 @@ typedef void (*ReorderBufferMessageCB) (ReorderBuffer *rb, const char *prefix, Size sz, const char *message); -/* sequence callback signature */ -typedef void (*ReorderBufferSequenceCB) (ReorderBuffer *rb, - ReorderBufferTXN *txn, - XLogRecPtr sequence_lsn, - Relation rel, - bool transactional, - int64 last_value, int64 log_cnt, - bool is_called); - /* begin prepare callback signature */ typedef void (*ReorderBufferBeginPrepareCB) (ReorderBuffer *rb, ReorderBufferTXN *txn); @@ -513,15 +496,6 @@ typedef void (*ReorderBufferStreamMessageCB) ( const char *prefix, Size sz, const char *message); -/* stream sequence callback signature */ -typedef void (*ReorderBufferStreamSequenceCB) (ReorderBuffer *rb, - ReorderBufferTXN *txn, - XLogRecPtr sequence_lsn, - Relation rel, - bool transactional, - int64 last_value, int64 log_cnt, - bool is_called); - /* stream truncate callback signature */ typedef void (*ReorderBufferStreamTruncateCB) ( ReorderBuffer *rb, @@ -538,12 +512,6 @@ struct ReorderBuffer HTAB *by_txn; /* - * relfilenode => XID lookup table for sequences created in a transaction - * (also includes altered sequences, which assigns new relfilenode) - */ - HTAB *sequences; - - /* * Transactions that could be a toplevel xact, ordered by LSN of the first * record bearing that xid. */ @@ -573,7 +541,6 @@ struct ReorderBuffer ReorderBufferApplyTruncateCB apply_truncate; ReorderBufferCommitCB commit; ReorderBufferMessageCB message; - ReorderBufferSequenceCB sequence; /* * Callbacks to be called when streaming a transaction at prepare time. @@ -593,7 +560,6 @@ struct ReorderBuffer ReorderBufferStreamCommitCB stream_commit; ReorderBufferStreamChangeCB stream_change; ReorderBufferStreamMessageCB stream_message; - ReorderBufferStreamSequenceCB stream_sequence; ReorderBufferStreamTruncateCB stream_truncate; /* @@ -669,10 +635,6 @@ void ReorderBufferQueueChange(ReorderBuffer *, TransactionId, void ReorderBufferQueueMessage(ReorderBuffer *, TransactionId, Snapshot snapshot, XLogRecPtr lsn, bool transactional, const char *prefix, Size message_size, const char *message); -void ReorderBufferQueueSequence(ReorderBuffer *rb, TransactionId xid, - Snapshot snapshot, XLogRecPtr lsn, RepOriginId origin_id, - RelFileNode rnode, bool transactional, bool created, - ReorderBufferTupleBuf *tuplebuf); void ReorderBufferCommit(ReorderBuffer *, TransactionId, XLogRecPtr commit_lsn, XLogRecPtr end_lsn, TimestampTz commit_time, RepOriginId origin_id, XLogRecPtr origin_lsn); @@ -720,7 +682,4 @@ void ReorderBufferSetRestartPoint(ReorderBuffer *, XLogRecPtr ptr); void StartupReorderBuffer(void); -bool ReorderBufferSequenceIsTransactional(ReorderBuffer *rb, - RelFileNode rnode, bool created); - #endif diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out index c95d44b3db9..4117fc27c9a 100644 --- a/src/test/regress/expected/object_address.out +++ b/src/test/regress/expected/object_address.out @@ -46,7 +46,6 @@ CREATE TRANSFORM FOR int LANGUAGE SQL ( SET client_min_messages = 'ERROR'; CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; CREATE PUBLICATION addr_pub_schema FOR ALL TABLES IN SCHEMA addr_nsp; -CREATE PUBLICATION addr_pub_schema2 FOR ALL SEQUENCES IN SCHEMA addr_nsp; RESET client_min_messages; CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables @@ -429,8 +428,7 @@ WITH objects (type, name, args) AS (VALUES ('transform', '{int}', '{sql}'), ('access method', '{btree}', '{}'), ('publication', '{addr_pub}', '{}'), - ('publication namespace', '{addr_nsp}', '{addr_pub_schema,t}'), - ('publication namespace', '{addr_nsp}', '{addr_pub_schema2,s}'), + ('publication namespace', '{addr_nsp}', '{addr_pub_schema}'), ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), ('subscription', '{regress_addr_sub}', '{}'), ('statistics object', '{addr_nsp, gentable_stat}', '{}') @@ -494,9 +492,8 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, subscription | | regress_addr_sub | regress_addr_sub | t publication | | addr_pub | addr_pub | t publication relation | | | addr_nsp.gentable in publication addr_pub | t - publication namespace | | | addr_nsp in publication addr_pub_schema type t | t - publication namespace | | | addr_nsp in publication addr_pub_schema2 type s | t -(51 rows) + publication namespace | | | addr_nsp in publication addr_pub_schema | t +(50 rows) --- --- Cleanup resources @@ -509,7 +506,6 @@ drop cascades to server integer drop cascades to user mapping for regress_addr_user on server integer DROP PUBLICATION addr_pub; DROP PUBLICATION addr_pub_schema; -DROP PUBLICATION addr_pub_schema2; DROP SUBSCRIPTION regress_addr_sub; DROP SCHEMA addr_nsp CASCADE; NOTICE: drop cascades to 14 other objects diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out index 0308e40ba6c..4d24d772bde 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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------+--------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - testpib_ins_trunct | regress_publication_user | f | f | t | f | f | f | f | f - testpub_default | regress_publication_user | f | f | f | t | f | f | f | f + 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 (2 rows) -ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete, sequence'); +ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete'); \dRp - List of publications - Name | Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------+--------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - testpib_ins_trunct | regress_publication_user | f | f | t | f | f | f | f | f - testpub_default | regress_publication_user | f | f | t | t | t | f | t | f + 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 (2 rows) --- adding tables @@ -61,9 +61,6 @@ CREATE TABLE testpub_tbl2 (id serial primary key, data text); ALTER PUBLICATION testpub_foralltables ADD TABLE testpub_tbl2; ERROR: publication "testpub_foralltables" is defined as FOR ALL TABLES DETAIL: Tables cannot be added to or dropped from FOR ALL TABLES publications. --- fail - can't add a table using ADD SEQUENCE command -ALTER PUBLICATION testpub_foralltables ADD SEQUENCE testpub_tbl2; -ERROR: object type does not match type expected by command -- fail - can't drop from all tables publication ALTER PUBLICATION testpub_foralltables DROP TABLE testpub_tbl2; ERROR: publication "testpub_foralltables" is defined as FOR ALL TABLES @@ -90,10 +87,10 @@ RESET client_min_messages; -- should be able to add schema to 'FOR TABLE' publication ALTER PUBLICATION testpub_fortable ADD ALL TABLES IN SCHEMA pub_test; \dRp+ testpub_fortable - Publication testpub_fortable - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_fortable + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables: "public.testpub_tbl1" Tables from schemas: @@ -102,20 +99,20 @@ Tables from schemas: -- should be able to drop schema from 'FOR TABLE' publication ALTER PUBLICATION testpub_fortable DROP ALL TABLES IN SCHEMA pub_test; \dRp+ testpub_fortable - Publication testpub_fortable - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_fortable + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | 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 ALL TABLES IN SCHEMA pub_test; \dRp+ testpub_fortable - Publication testpub_fortable - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_fortable + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test" @@ -137,10 +134,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables: "pub_test.testpub_nopk" @@ -162,10 +159,10 @@ Publications: "testpub_foralltables" \dRp+ testpub_foralltables - Publication testpub_foralltables - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | t | f | t | t | f | f | f | f + Publication testpub_foralltables + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | t | t | t | f | f | f (1 row) DROP TABLE testpub_tbl2; @@ -177,545 +174,24 @@ 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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub3 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables: "public.testpub_tbl3" "public.testpub_tbl3a" \dRp+ testpub4 - Publication testpub4 - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub4 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | 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 WITH (publish = 'sequence'); -RESET client_min_messages; -ALTER PUBLICATION testpub_forallsequences SET (publish = 'insert, sequence'); -CREATE SEQUENCE testpub_seq2; --- fail - can't add to for all sequences publication -ALTER PUBLICATION testpub_forallsequences ADD SEQUENCE testpub_seq2; -ERROR: publication "testpub_forallsequences" is defined as FOR ALL SEQUENCES -DETAIL: Sequences cannot be added to or dropped from FOR ALL SEQUENCES publications. --- fail - can't drop from all sequences publication -ALTER PUBLICATION testpub_forallsequences DROP SEQUENCE testpub_seq2; -ERROR: publication "testpub_forallsequences" is defined as FOR ALL SEQUENCES -DETAIL: Sequences cannot be added to or dropped from FOR ALL SEQUENCES publications. --- fail - can't add to for all sequences publication -ALTER PUBLICATION testpub_forallsequences SET SEQUENCE pub_test.testpub_seq1; -ERROR: publication "testpub_forallsequences" is defined as FOR ALL SEQUENCES -DETAIL: Sequences cannot be added to or dropped from FOR ALL SEQUENCES publications. --- fail - can't add schema to 'FOR ALL SEQUENCES' publication -ALTER PUBLICATION testpub_forallsequences ADD ALL SEQUENCES IN SCHEMA pub_test; -ERROR: publication "testpub_forallsequences" is defined as FOR ALL SEQUENCES -DETAIL: Sequences from schema cannot be added to, dropped from, or set on FOR ALL SEQUENCES publications. --- fail - can't drop schema from 'FOR ALL SEQUENCES' publication -ALTER PUBLICATION testpub_forallsequences DROP ALL SEQUENCES IN SCHEMA pub_test; -ERROR: publication "testpub_forallsequences" is defined as FOR ALL SEQUENCES -DETAIL: Sequences from schema cannot be added to, dropped from, or set on FOR ALL SEQUENCES publications. --- fail - can't set schema to 'FOR ALL SEQUENCES' publication -ALTER PUBLICATION testpub_forallsequences SET ALL SEQUENCES IN SCHEMA pub_test; -ERROR: publication "testpub_forallsequences" is defined as FOR ALL SEQUENCES -DETAIL: Sequences from schema cannot be added to, dropped from, or set on FOR ALL SEQUENCES publications. -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_forsequence FOR SEQUENCE testpub_seq0; -RESET client_min_messages; --- should be able to add schema to 'FOR SEQUENCE' publication -ALTER PUBLICATION testpub_forsequence ADD ALL SEQUENCES IN SCHEMA pub_test; -\dRp+ testpub_forsequence - Publication testpub_forsequence - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Sequences: - "public.testpub_seq0" -Sequences from schemas: - "pub_test" - --- fail - can't add sequence from the schema we already added -ALTER PUBLICATION testpub_forsequence ADD SEQUENCE pub_test.testpub_seq1; -ERROR: cannot add relation "pub_test.testpub_seq1" to publication -DETAIL: Sequence's schema "pub_test" is already part of the publication or part of the specified schema list. --- fail - can't add sequence using ADD TABLE command -ALTER PUBLICATION testpub_forsequence ADD TABLE pub_test.testpub_seq1; -ERROR: object type does not match type expected by command --- should be able to drop schema from 'FOR SEQUENCE' publication -ALTER PUBLICATION testpub_forsequence DROP ALL SEQUENCES IN SCHEMA pub_test; -\dRp+ testpub_forsequence - Publication testpub_forsequence - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Sequences: - "public.testpub_seq0" - --- should be able to set schema to 'FOR SEQUENCE' publication -ALTER PUBLICATION testpub_forsequence SET ALL SEQUENCES IN SCHEMA pub_test; -\dRp+ testpub_forsequence - Publication testpub_forsequence - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Sequences from schemas: - "pub_test" - -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_forschema FOR ALL SEQUENCES IN SCHEMA pub_test; -RESET client_min_messages; --- fail - can't create publication with schema and sequence of the same schema -CREATE PUBLICATION testpub_for_seq_schema FOR ALL SEQUENCES IN SCHEMA pub_test, SEQUENCE pub_test.testpub_seq1; -ERROR: cannot add relation "pub_test.testpub_seq1" to publication -DETAIL: Sequence's schema "pub_test" is already part of the publication or part of the specified schema list. --- fail - can't add a sequence of the same schema to the schema publication -ALTER PUBLICATION testpub_forschema ADD SEQUENCE pub_test.testpub_seq1; -ERROR: cannot add relation "pub_test.testpub_seq1" to publication -DETAIL: Sequence's schema "pub_test" is already part of the publication or part of the specified schema list. --- fail - can't drop a sequence from the schema publication which isn't in the --- publication -ALTER PUBLICATION testpub_forschema DROP SEQUENCE pub_test.testpub_seq1; -ERROR: relation "testpub_seq1" is not part of the publication --- should be able to set sequence to schema publication -ALTER PUBLICATION testpub_forschema SET SEQUENCE pub_test.testpub_seq1; -\dRp+ testpub_forschema - Publication testpub_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Sequences: - "pub_test.testpub_seq1" - -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" - "testpub_forschema" - "testpub_forsequence" - -\dRp+ testpub_forallsequences - Publication testpub_forallsequences - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | t | t | f | f | f | t | f -(1 row) - -DROP SEQUENCE testpub_seq0, pub_test.testpub_seq1, testpub_seq2; -DROP PUBLICATION testpub_forallsequences, testpub_forsequence, testpub_forschema; --- publication testing multiple sequences at the same time -CREATE SEQUENCE testpub_seq1; -CREATE SEQUENCE testpub_seq2; -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_multi FOR SEQUENCE testpub_seq1, testpub_seq2; -RESET client_min_messages; -\dRp+ testpub_multi - Publication testpub_multi - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Sequences: - "public.testpub_seq1" - "public.testpub_seq2" - -DROP PUBLICATION testpub_multi; -DROP SEQUENCE testpub_seq1; -DROP SEQUENCE testpub_seq2; --- Publication mixing tables and sequences -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_mix; -RESET client_min_messages; -CREATE SEQUENCE testpub_seq1; -CREATE SEQUENCE pub_test.testpub_seq2; -ALTER PUBLICATION testpub_mix ADD SEQUENCE testpub_seq1, TABLE testpub_tbl1; -\dRp+ testpub_mix - Publication testpub_mix - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables: - "public.testpub_tbl1" -Sequences: - "public.testpub_seq1" - -ALTER PUBLICATION testpub_mix ADD ALL SEQUENCES IN SCHEMA pub_test, ALL TABLES IN SCHEMA pub_test; -\dRp+ testpub_mix - Publication testpub_mix - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables: - "public.testpub_tbl1" -Tables from schemas: - "pub_test" -Sequences: - "public.testpub_seq1" -Sequences from schemas: - "pub_test" - -ALTER PUBLICATION testpub_mix DROP ALL SEQUENCES IN SCHEMA pub_test; -\dRp+ testpub_mix - Publication testpub_mix - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables: - "public.testpub_tbl1" -Tables from schemas: - "pub_test" -Sequences: - "public.testpub_seq1" - -ALTER PUBLICATION testpub_mix DROP ALL TABLES IN SCHEMA pub_test; -\dRp+ testpub_mix - Publication testpub_mix - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables: - "public.testpub_tbl1" -Sequences: - "public.testpub_seq1" - -DROP PUBLICATION testpub_mix; -DROP SEQUENCE testpub_seq1; -DROP SEQUENCE pub_test.testpub_seq2; --- make sure we replicate only the correct relation type -CREATE SCHEMA pub_test1; -CREATE SEQUENCE pub_test1.test_seq1; -CREATE TABLE pub_test1.test_tbl1 (a int primary key, b int); -CREATE SCHEMA pub_test2; -CREATE SEQUENCE pub_test2.test_seq2; -CREATE TABLE pub_test2.test_tbl2 (a int primary key, b int); -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_schemas; -RESET client_min_messages; --- add tables from one schema, sequences from the other -ALTER PUBLICATION testpub_schemas ADD ALL TABLES IN SCHEMA pub_test2; -ALTER PUBLICATION testpub_schemas ADD ALL SEQUENCES IN SCHEMA pub_test1; -\dRp+ testpub_schemas - Publication testpub_schemas - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables from schemas: - "pub_test2" -Sequences from schemas: - "pub_test1" - -\dn+ pub_test1 - List of schemas - Name | Owner | Access privileges | Description ------------+--------------------------+-------------------+------------- - pub_test1 | regress_publication_user | | -Publications: - "testpub_schemas" (sequences) - -\dn+ pub_test2 - List of schemas - Name | Owner | Access privileges | Description ------------+--------------------------+-------------------+------------- - pub_test2 | regress_publication_user | | -Publications: - "testpub_schemas" (tables) - -\d+ pub_test1.test_seq1; - Sequence "pub_test1.test_seq1" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 -Publications: - "testpub_schemas" - -\d+ pub_test1.test_tbl1; - Table "pub_test1.test_tbl1" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl1_pkey" PRIMARY KEY, btree (a) - -\d+ pub_test2.test_seq2; - Sequence "pub_test2.test_seq2" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 - -\d+ pub_test2.test_tbl2; - Table "pub_test2.test_tbl2" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl2_pkey" PRIMARY KEY, btree (a) -Publications: - "testpub_schemas" - --- add the other object type from each schema -ALTER PUBLICATION testpub_schemas ADD ALL TABLES IN SCHEMA pub_test1; -ALTER PUBLICATION testpub_schemas ADD ALL SEQUENCES IN SCHEMA pub_test2; -\dRp+ testpub_schemas - Publication testpub_schemas - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables from schemas: - "pub_test1" - "pub_test2" -Sequences from schemas: - "pub_test1" - "pub_test2" - -\dn+ pub_test1 - List of schemas - Name | Owner | Access privileges | Description ------------+--------------------------+-------------------+------------- - pub_test1 | regress_publication_user | | -Publications: - "testpub_schemas" (sequences) - "testpub_schemas" (tables) - -\dn+ pub_test2 - List of schemas - Name | Owner | Access privileges | Description ------------+--------------------------+-------------------+------------- - pub_test2 | regress_publication_user | | -Publications: - "testpub_schemas" (tables) - "testpub_schemas" (sequences) - -\d+ pub_test1.test_seq1; - Sequence "pub_test1.test_seq1" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 -Publications: - "testpub_schemas" - -\d+ pub_test1.test_tbl1; - Table "pub_test1.test_tbl1" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl1_pkey" PRIMARY KEY, btree (a) -Publications: - "testpub_schemas" - -\d+ pub_test2.test_seq2; - Sequence "pub_test2.test_seq2" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 -Publications: - "testpub_schemas" - -\d+ pub_test2.test_tbl2; - Table "pub_test2.test_tbl2" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl2_pkey" PRIMARY KEY, btree (a) -Publications: - "testpub_schemas" - --- now drop the object type added first -ALTER PUBLICATION testpub_schemas DROP ALL TABLES IN SCHEMA pub_test2; -ALTER PUBLICATION testpub_schemas DROP ALL SEQUENCES IN SCHEMA pub_test1; -\dRp+ testpub_schemas - Publication testpub_schemas - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables from schemas: - "pub_test1" -Sequences from schemas: - "pub_test2" - -\dn+ pub_test1 - List of schemas - Name | Owner | Access privileges | Description ------------+--------------------------+-------------------+------------- - pub_test1 | regress_publication_user | | -Publications: - "testpub_schemas" (tables) - -\dn+ pub_test2 - List of schemas - Name | Owner | Access privileges | Description ------------+--------------------------+-------------------+------------- - pub_test2 | regress_publication_user | | -Publications: - "testpub_schemas" (sequences) - -\d+ pub_test1.test_seq1; - Sequence "pub_test1.test_seq1" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 - -\d+ pub_test1.test_tbl1; - Table "pub_test1.test_tbl1" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl1_pkey" PRIMARY KEY, btree (a) -Publications: - "testpub_schemas" - -\d+ pub_test2.test_seq2; - Sequence "pub_test2.test_seq2" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 -Publications: - "testpub_schemas" - -\d+ pub_test2.test_tbl2; - Table "pub_test2.test_tbl2" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl2_pkey" PRIMARY KEY, btree (a) - --- should fail (publication contains the whole schema) -ALTER PUBLICATION testpub_schemas ADD TABLE pub_test1.test_tbl1; -ERROR: cannot add relation "pub_test1.test_tbl1" to publication -DETAIL: Table's schema "pub_test1" is already part of the publication or part of the specified schema list. -ALTER PUBLICATION testpub_schemas ADD SEQUENCE pub_test2.test_seq2; -ERROR: cannot add relation "pub_test2.test_seq2" to publication -DETAIL: Sequence's schema "pub_test2" is already part of the publication or part of the specified schema list. --- should work (different schema) -ALTER PUBLICATION testpub_schemas ADD TABLE pub_test2.test_tbl2; -ALTER PUBLICATION testpub_schemas ADD SEQUENCE pub_test1.test_seq1; -\dRp+ testpub_schemas - Publication testpub_schemas - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables: - "pub_test2.test_tbl2" -Tables from schemas: - "pub_test1" -Sequences: - "pub_test1.test_seq1" -Sequences from schemas: - "pub_test2" - -\d+ pub_test1.test_seq1; - Sequence "pub_test1.test_seq1" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 -Publications: - "testpub_schemas" - -\d+ pub_test1.test_tbl1; - Table "pub_test1.test_tbl1" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl1_pkey" PRIMARY KEY, btree (a) -Publications: - "testpub_schemas" - -\d+ pub_test2.test_seq2; - Sequence "pub_test2.test_seq2" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 -Publications: - "testpub_schemas" - -\d+ pub_test2.test_tbl2; - Table "pub_test2.test_tbl2" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl2_pkey" PRIMARY KEY, btree (a) -Publications: - "testpub_schemas" - --- now drop the explicitly added objects again -ALTER PUBLICATION testpub_schemas DROP TABLE pub_test2.test_tbl2; -ALTER PUBLICATION testpub_schemas DROP SEQUENCE pub_test1.test_seq1; -\dRp+ testpub_schemas - Publication testpub_schemas - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f -Tables from schemas: - "pub_test1" -Sequences from schemas: - "pub_test2" - -\d+ pub_test1.test_seq1; - Sequence "pub_test1.test_seq1" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 - -\d+ pub_test1.test_tbl1; - Table "pub_test1.test_tbl1" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl1_pkey" PRIMARY KEY, btree (a) -Publications: - "testpub_schemas" - -\d+ pub_test2.test_seq2; - Sequence "pub_test2.test_seq2" - Type | Start | Minimum | Maximum | Increment | Cycles? | Cache ---------+-------+---------+---------------------+-----------+---------+------- - bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 -Publications: - "testpub_schemas" - -\d+ pub_test2.test_tbl2; - Table "pub_test2.test_tbl2" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | not null | | plain | | - b | integer | | | | plain | | -Indexes: - "test_tbl2_pkey" PRIMARY KEY, btree (a) - -DROP PUBLICATION testpub_schemas; -DROP TABLE pub_test1.test_tbl1, pub_test2.test_tbl2; -DROP SEQUENCE pub_test1.test_seq1, pub_test2.test_seq2; -DROP SCHEMA pub_test1, pub_test2; -- Tests for partitioned tables SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_forparted; @@ -731,10 +207,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_forparted + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables: "public.testpub_parted" @@ -747,10 +223,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | t + Publication testpub_forparted + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | t Tables: "public.testpub_parted" @@ -779,10 +255,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | f | f | f | f | f + Publication testpub5 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "public.testpub_rf_tbl2" WHERE ((c <> 'test'::text) AND (d < 5)) @@ -795,10 +271,10 @@ Tables: ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl3 WHERE (e > 1000 AND e < 2000); \dRp+ testpub5 - Publication testpub5 - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | f | f | f | f | f + Publication testpub5 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "public.testpub_rf_tbl2" WHERE ((c <> 'test'::text) AND (d < 5)) @@ -814,10 +290,10 @@ Publications: ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl2; \dRp+ testpub5 - Publication testpub5 - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | f | f | f | f | f + Publication testpub5 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "public.testpub_rf_tbl3" WHERE ((e > 1000) AND (e < 2000)) @@ -825,10 +301,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | f | f | f | f | f + Publication testpub5 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | f | f | f | f Tables: "public.testpub_rf_tbl3" WHERE ((e > 300) AND (e < 500)) @@ -861,10 +337,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | f | f | f | f | f + Publication testpub_syntax1 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "public.testpub_rf_tbl3" WHERE (e < 999) @@ -874,10 +350,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | f | f | f | f | f + Publication testpub_syntax2 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | f | f | f | f Tables: "public.testpub_rf_tbl1" "testpub_rf_schema1.testpub_rf_tbl5" WHERE (h < 999) @@ -1196,10 +672,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | f | f | t | f | f + Publication testpub_table_ins + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | f | f | t | f Tables: "public.testpub_tbl5" (a) @@ -1341,10 +817,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_both_filters + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables: "public.testpub_tbl_both_filters" (a, c) WHERE (c <> 1) @@ -1545,10 +1021,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_fortbl + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables: "pub_test.testpub_nopk" "public.testpub_tbl1" @@ -1586,10 +1062,10 @@ Publications: "testpub_fortbl" \dRp+ testpub_default - Publication testpub_default - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | f | t | f + Publication testpub_default + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | f | f Tables: "pub_test.testpub_nopk" "public.testpub_tbl1" @@ -1667,10 +1143,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | f | t | f + Publication testpub_default + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | f | f (1 row) -- fail - must be owner of publication @@ -1680,20 +1156,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root --------------+--------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - testpub_foo | regress_publication_user | f | f | t | t | t | f | t | f + List of publications + Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +-------------+--------------------------+------------+---------+---------+---------+-----------+---------- + testpub_foo | regress_publication_user | 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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ------------------+---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - testpub_default | regress_publication_user2 | f | f | t | t | t | f | t | f + List of publications + Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +-----------------+---------------------------+------------+---------+---------+---------+-----------+---------- + testpub_default | regress_publication_user2 | f | t | t | t | f | f (1 row) -- adding schemas and tables @@ -1709,19 +1185,19 @@ CREATE TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA"(id int); SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub1_forschema FOR ALL TABLES IN SCHEMA pub_test1; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" CREATE PUBLICATION testpub2_forschema FOR ALL TABLES IN SCHEMA pub_test1, pub_test2, pub_test3; \dRp+ testpub2_forschema - Publication testpub2_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub2_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1735,44 +1211,44 @@ CREATE PUBLICATION testpub6_forschema FOR ALL TABLES IN SCHEMA "CURRENT_SCHEMA", CREATE PUBLICATION testpub_fortable FOR TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA"; RESET client_min_messages; \dRp+ testpub3_forschema - Publication testpub3_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub3_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "public" \dRp+ testpub4_forschema - Publication testpub4_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub4_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "CURRENT_SCHEMA" \dRp+ testpub5_forschema - Publication testpub5_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub5_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "CURRENT_SCHEMA" "public" \dRp+ testpub6_forschema - Publication testpub6_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub6_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "CURRENT_SCHEMA" "public" \dRp+ testpub_fortable - Publication testpub_fortable - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_fortable + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables: "CURRENT_SCHEMA.CURRENT_SCHEMA" @@ -1806,10 +1282,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub2_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1817,20 +1293,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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub2_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | 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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub2_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1838,10 +1314,10 @@ Tables from schemas: -- alter publication add schema ALTER PUBLICATION testpub1_forschema ADD ALL TABLES IN SCHEMA pub_test2; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1850,10 +1326,10 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema ADD ALL TABLES IN SCHEMA non_existent_schema; ERROR: schema "non_existent_schema" does not exist \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1862,10 +1338,10 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema ADD ALL 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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1873,10 +1349,10 @@ Tables from schemas: -- alter publication drop schema ALTER PUBLICATION testpub1_forschema DROP ALL TABLES IN SCHEMA pub_test2; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" @@ -1884,10 +1360,10 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema DROP ALL 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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" @@ -1895,29 +1371,29 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema DROP ALL TABLES IN SCHEMA non_existent_schema; ERROR: schema "non_existent_schema" does not exist \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" -- drop all schemas ALTER PUBLICATION testpub1_forschema DROP ALL TABLES IN SCHEMA pub_test1; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f (1 row) -- alter publication set multiple schema ALTER PUBLICATION testpub1_forschema SET ALL TABLES IN SCHEMA pub_test1, pub_test2; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1926,10 +1402,10 @@ Tables from schemas: ALTER PUBLICATION testpub1_forschema SET ALL TABLES IN SCHEMA non_existent_schema; ERROR: schema "non_existent_schema" does not exist \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" "pub_test2" @@ -1938,10 +1414,10 @@ Tables from schemas: -- removing the duplicate schemas ALTER PUBLICATION testpub1_forschema SET ALL TABLES IN SCHEMA pub_test1, pub_test1; \dRp+ testpub1_forschema - Publication testpub1_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub1_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" @@ -2020,18 +1496,18 @@ SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub3_forschema; RESET client_min_messages; \dRp+ testpub3_forschema - Publication testpub3_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub3_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f (1 row) ALTER PUBLICATION testpub3_forschema SET ALL TABLES IN SCHEMA pub_test1; \dRp+ testpub3_forschema - Publication testpub3_forschema - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub3_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables from schemas: "pub_test1" @@ -2041,20 +1517,20 @@ CREATE PUBLICATION testpub_forschema_fortable FOR ALL TABLES IN SCHEMA pub_test1 CREATE PUBLICATION testpub_fortable_forschema FOR TABLE pub_test2.tbl1, ALL TABLES IN SCHEMA pub_test1; RESET client_min_messages; \dRp+ testpub_forschema_fortable - Publication testpub_forschema_fortable - Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_forschema_fortable + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | 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 | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root ---------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- - regress_publication_user | f | f | t | t | t | t | t | f + Publication testpub_fortable_forschema + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +--------------------------+------------+---------+---------+---------+-----------+---------- + regress_publication_user | f | t | t | t | t | f Tables: "pub_test2.tbl1" Tables from schemas: @@ -2098,85 +1574,40 @@ CREATE SCHEMA sch1; CREATE SCHEMA sch2; CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE(a); CREATE TABLE sch2.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) to (10); -CREATE SEQUENCE sch1.seq1; -CREATE SEQUENCE sch2.seq2; -- Schema publication that does not include the schema that has the parent table CREATE PUBLICATION pub FOR ALL TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=1); -ALTER PUBLICATION pub ADD ALL SEQUENCES IN SCHEMA sch2; SELECT * FROM pg_publication_tables; pubname | schemaname | tablename ---------+------------+------------ pub | sch2 | tbl1_part1 (1 row) -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch2 | seq2 -(1 row) - DROP PUBLICATION pub; -- Table publication that does not include the parent table CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=1); -ALTER PUBLICATION pub ADD SEQUENCE sch2.seq2; SELECT * FROM pg_publication_tables; pubname | schemaname | tablename ---------+------------+------------ pub | sch2 | tbl1_part1 (1 row) -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch2 | seq2 -(1 row) - -- Table publication that includes both the parent table and the child table ALTER PUBLICATION pub ADD TABLE sch1.tbl1; -ALTER PUBLICATION pub ADD SEQUENCE sch1.seq1; SELECT * FROM pg_publication_tables; pubname | schemaname | tablename ---------+------------+----------- pub | sch1 | tbl1 (1 row) -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch1 | seq1 - pub | sch2 | seq2 -(2 rows) - DROP PUBLICATION pub; -- Schema publication that does not include the schema that has the parent table CREATE PUBLICATION pub FOR ALL TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=0); -ALTER PUBLICATION pub ADD SEQUENCE sch1.seq1; SELECT * FROM pg_publication_tables; pubname | schemaname | tablename ---------+------------+------------ pub | sch2 | tbl1_part1 (1 row) -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch1 | seq1 -(1 row) - -DROP PUBLICATION pub; --- Sequence publication -CREATE PUBLICATION pub FOR SEQUENCE sch2.seq2; -SELECT * FROM pg_publication_tables; - pubname | schemaname | tablename ----------+------------+----------- -(0 rows) - -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch2 | seq2 -(1 row) - DROP PUBLICATION pub; -- Table publication that does not include the parent table CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=0); @@ -2186,26 +1617,14 @@ SELECT * FROM pg_publication_tables; pub | sch2 | tbl1_part1 (1 row) -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- -(0 rows) - -- Table publication that includes both the parent table and the child table ALTER PUBLICATION pub ADD TABLE sch1.tbl1; -ALTER PUBLICATION pub ADD ALL SEQUENCES IN SCHEMA sch2; SELECT * FROM pg_publication_tables; pubname | schemaname | tablename ---------+------------+------------ pub | sch2 | tbl1_part1 (1 row) -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch2 | seq2 -(1 row) - DROP PUBLICATION pub; DROP TABLE sch2.tbl1_part1; DROP TABLE sch1.tbl1; @@ -2221,81 +1640,9 @@ SELECT * FROM pg_publication_tables; pub | sch1 | tbl1 (1 row) -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- -(0 rows) - -DROP PUBLICATION pub; --- Schema publication -CREATE PUBLICATION pub FOR SEQUENCE sch2.seq2; -SELECT * FROM pg_publication_tables; - pubname | schemaname | tablename ----------+------------+----------- -(0 rows) - -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch2 | seq2 -(1 row) - -DROP PUBLICATION pub; --- Sequence publication -CREATE PUBLICATION pub FOR ALL SEQUENCES IN SCHEMA sch2; -SELECT * FROM pg_publication_tables; - pubname | schemaname | tablename ----------+------------+----------- -(0 rows) - -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch2 | seq2 -(1 row) - -ALTER PUBLICATION pub ADD SEQUENCE sch1.seq1; -SELECT * FROM pg_publication_tables; - pubname | schemaname | tablename ----------+------------+----------- -(0 rows) - -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch1 | seq1 - pub | sch2 | seq2 -(2 rows) - -ALTER PUBLICATION pub DROP SEQUENCE sch1.seq1; -SELECT * FROM pg_publication_tables; - pubname | schemaname | tablename ----------+------------+----------- -(0 rows) - -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch2 | seq2 -(1 row) - -ALTER PUBLICATION pub ADD ALL SEQUENCES IN SCHEMA sch1; -SELECT * FROM pg_publication_tables; - pubname | schemaname | tablename ----------+------------+----------- -(0 rows) - -SELECT * FROM pg_publication_sequences; - pubname | schemaname | sequencename ----------+------------+-------------- - pub | sch1 | seq1 - pub | sch2 | seq2 -(2 rows) - RESET client_min_messages; DROP PUBLICATION pub; DROP TABLE sch1.tbl1; -DROP SEQUENCE sch1.seq1, sch2.seq2; DROP SCHEMA sch1 cascade; DROP SCHEMA sch2 cascade; RESET SESSION AUTHORIZATION; diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index db652ea8d89..f29375c2a90 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1435,14 +1435,6 @@ 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/object_address.sql b/src/test/regress/sql/object_address.sql index 9d8323468d6..acd0468a9d9 100644 --- a/src/test/regress/sql/object_address.sql +++ b/src/test/regress/sql/object_address.sql @@ -49,7 +49,6 @@ CREATE TRANSFORM FOR int LANGUAGE SQL ( SET client_min_messages = 'ERROR'; CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; CREATE PUBLICATION addr_pub_schema FOR ALL TABLES IN SCHEMA addr_nsp; -CREATE PUBLICATION addr_pub_schema2 FOR ALL SEQUENCES IN SCHEMA addr_nsp; RESET client_min_messages; CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable; @@ -199,8 +198,7 @@ WITH objects (type, name, args) AS (VALUES ('transform', '{int}', '{sql}'), ('access method', '{btree}', '{}'), ('publication', '{addr_pub}', '{}'), - ('publication namespace', '{addr_nsp}', '{addr_pub_schema,t}'), - ('publication namespace', '{addr_nsp}', '{addr_pub_schema2,s}'), + ('publication namespace', '{addr_nsp}', '{addr_pub_schema}'), ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), ('subscription', '{regress_addr_sub}', '{}'), ('statistics object', '{addr_nsp, gentable_stat}', '{}') @@ -220,7 +218,6 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, DROP FOREIGN DATA WRAPPER addr_fdw CASCADE; DROP PUBLICATION addr_pub; DROP PUBLICATION addr_pub_schema; -DROP PUBLICATION addr_pub_schema2; DROP SUBSCRIPTION regress_addr_sub; DROP SCHEMA addr_nsp CASCADE; diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql index 96b02947fa2..8539110025e 100644 --- a/src/test/regress/sql/publication.sql +++ b/src/test/regress/sql/publication.sql @@ -27,7 +27,7 @@ CREATE PUBLICATION testpub_xxx WITH (publish_via_partition_root = 'true', publis \dRp -ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete, sequence'); +ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete'); \dRp @@ -46,8 +46,6 @@ ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update'); CREATE TABLE testpub_tbl2 (id serial primary key, data text); -- fail - can't add to for all tables publication ALTER PUBLICATION testpub_foralltables ADD TABLE testpub_tbl2; --- fail - can't add a table using ADD SEQUENCE command -ALTER PUBLICATION testpub_foralltables ADD SEQUENCE testpub_tbl2; -- fail - can't drop from all tables publication ALTER PUBLICATION testpub_foralltables DROP TABLE testpub_tbl2; -- fail - can't add to for all tables publication @@ -106,199 +104,6 @@ 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 WITH (publish = 'sequence'); -RESET client_min_messages; -ALTER PUBLICATION testpub_forallsequences SET (publish = 'insert, sequence'); - -CREATE SEQUENCE testpub_seq2; --- fail - can't add to for all sequences publication -ALTER PUBLICATION testpub_forallsequences ADD SEQUENCE testpub_seq2; --- fail - can't drop from all sequences publication -ALTER PUBLICATION testpub_forallsequences DROP SEQUENCE testpub_seq2; --- fail - can't add to for all sequences publication -ALTER PUBLICATION testpub_forallsequences SET SEQUENCE pub_test.testpub_seq1; - --- fail - can't add schema to 'FOR ALL SEQUENCES' publication -ALTER PUBLICATION testpub_forallsequences ADD ALL SEQUENCES IN SCHEMA pub_test; --- fail - can't drop schema from 'FOR ALL SEQUENCES' publication -ALTER PUBLICATION testpub_forallsequences DROP ALL SEQUENCES IN SCHEMA pub_test; --- fail - can't set schema to 'FOR ALL SEQUENCES' publication -ALTER PUBLICATION testpub_forallsequences SET ALL SEQUENCES IN SCHEMA pub_test; - -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_forsequence FOR SEQUENCE testpub_seq0; -RESET client_min_messages; --- should be able to add schema to 'FOR SEQUENCE' publication -ALTER PUBLICATION testpub_forsequence ADD ALL SEQUENCES IN SCHEMA pub_test; -\dRp+ testpub_forsequence --- fail - can't add sequence from the schema we already added -ALTER PUBLICATION testpub_forsequence ADD SEQUENCE pub_test.testpub_seq1; --- fail - can't add sequence using ADD TABLE command -ALTER PUBLICATION testpub_forsequence ADD TABLE pub_test.testpub_seq1; --- should be able to drop schema from 'FOR SEQUENCE' publication -ALTER PUBLICATION testpub_forsequence DROP ALL SEQUENCES IN SCHEMA pub_test; -\dRp+ testpub_forsequence --- should be able to set schema to 'FOR SEQUENCE' publication -ALTER PUBLICATION testpub_forsequence SET ALL SEQUENCES IN SCHEMA pub_test; -\dRp+ testpub_forsequence - -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_forschema FOR ALL SEQUENCES IN SCHEMA pub_test; -RESET client_min_messages; --- fail - can't create publication with schema and sequence of the same schema -CREATE PUBLICATION testpub_for_seq_schema FOR ALL SEQUENCES IN SCHEMA pub_test, SEQUENCE pub_test.testpub_seq1; --- fail - can't add a sequence of the same schema to the schema publication -ALTER PUBLICATION testpub_forschema ADD SEQUENCE pub_test.testpub_seq1; --- fail - can't drop a sequence from the schema publication which isn't in the --- publication -ALTER PUBLICATION testpub_forschema DROP SEQUENCE pub_test.testpub_seq1; --- should be able to set sequence to schema publication -ALTER PUBLICATION testpub_forschema SET SEQUENCE pub_test.testpub_seq1; -\dRp+ testpub_forschema - -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, testpub_seq2; -DROP PUBLICATION testpub_forallsequences, testpub_forsequence, testpub_forschema; - - --- publication testing multiple sequences at the same time -CREATE SEQUENCE testpub_seq1; -CREATE SEQUENCE testpub_seq2; - -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_multi FOR SEQUENCE testpub_seq1, testpub_seq2; -RESET client_min_messages; - -\dRp+ testpub_multi - -DROP PUBLICATION testpub_multi; -DROP SEQUENCE testpub_seq1; -DROP SEQUENCE testpub_seq2; - - --- Publication mixing tables and sequences -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_mix; -RESET client_min_messages; - -CREATE SEQUENCE testpub_seq1; -CREATE SEQUENCE pub_test.testpub_seq2; - -ALTER PUBLICATION testpub_mix ADD SEQUENCE testpub_seq1, TABLE testpub_tbl1; -\dRp+ testpub_mix - -ALTER PUBLICATION testpub_mix ADD ALL SEQUENCES IN SCHEMA pub_test, ALL TABLES IN SCHEMA pub_test; -\dRp+ testpub_mix - -ALTER PUBLICATION testpub_mix DROP ALL SEQUENCES IN SCHEMA pub_test; -\dRp+ testpub_mix - -ALTER PUBLICATION testpub_mix DROP ALL TABLES IN SCHEMA pub_test; -\dRp+ testpub_mix - -DROP PUBLICATION testpub_mix; -DROP SEQUENCE testpub_seq1; -DROP SEQUENCE pub_test.testpub_seq2; - - --- make sure we replicate only the correct relation type -CREATE SCHEMA pub_test1; -CREATE SEQUENCE pub_test1.test_seq1; -CREATE TABLE pub_test1.test_tbl1 (a int primary key, b int); - -CREATE SCHEMA pub_test2; -CREATE SEQUENCE pub_test2.test_seq2; -CREATE TABLE pub_test2.test_tbl2 (a int primary key, b int); - -SET client_min_messages = 'ERROR'; -CREATE PUBLICATION testpub_schemas; -RESET client_min_messages; - --- add tables from one schema, sequences from the other -ALTER PUBLICATION testpub_schemas ADD ALL TABLES IN SCHEMA pub_test2; -ALTER PUBLICATION testpub_schemas ADD ALL SEQUENCES IN SCHEMA pub_test1; - -\dRp+ testpub_schemas - -\dn+ pub_test1 -\dn+ pub_test2 - -\d+ pub_test1.test_seq1; -\d+ pub_test1.test_tbl1; - -\d+ pub_test2.test_seq2; -\d+ pub_test2.test_tbl2; - --- add the other object type from each schema -ALTER PUBLICATION testpub_schemas ADD ALL TABLES IN SCHEMA pub_test1; -ALTER PUBLICATION testpub_schemas ADD ALL SEQUENCES IN SCHEMA pub_test2; - -\dRp+ testpub_schemas - -\dn+ pub_test1 -\dn+ pub_test2 - -\d+ pub_test1.test_seq1; -\d+ pub_test1.test_tbl1; - -\d+ pub_test2.test_seq2; -\d+ pub_test2.test_tbl2; - --- now drop the object type added first -ALTER PUBLICATION testpub_schemas DROP ALL TABLES IN SCHEMA pub_test2; -ALTER PUBLICATION testpub_schemas DROP ALL SEQUENCES IN SCHEMA pub_test1; - -\dRp+ testpub_schemas - -\dn+ pub_test1 -\dn+ pub_test2 - -\d+ pub_test1.test_seq1; -\d+ pub_test1.test_tbl1; - -\d+ pub_test2.test_seq2; -\d+ pub_test2.test_tbl2; - --- should fail (publication contains the whole schema) -ALTER PUBLICATION testpub_schemas ADD TABLE pub_test1.test_tbl1; -ALTER PUBLICATION testpub_schemas ADD SEQUENCE pub_test2.test_seq2; - --- should work (different schema) -ALTER PUBLICATION testpub_schemas ADD TABLE pub_test2.test_tbl2; -ALTER PUBLICATION testpub_schemas ADD SEQUENCE pub_test1.test_seq1; - -\dRp+ testpub_schemas - -\d+ pub_test1.test_seq1; -\d+ pub_test1.test_tbl1; - -\d+ pub_test2.test_seq2; -\d+ pub_test2.test_tbl2; - --- now drop the explicitly added objects again -ALTER PUBLICATION testpub_schemas DROP TABLE pub_test2.test_tbl2; -ALTER PUBLICATION testpub_schemas DROP SEQUENCE pub_test1.test_seq1; - -\dRp+ testpub_schemas - -\d+ pub_test1.test_seq1; -\d+ pub_test1.test_tbl1; - -\d+ pub_test2.test_seq2; -\d+ pub_test2.test_tbl2; - -DROP PUBLICATION testpub_schemas; -DROP TABLE pub_test1.test_tbl1, pub_test2.test_tbl2; -DROP SEQUENCE pub_test1.test_seq1, pub_test2.test_seq2; -DROP SCHEMA pub_test1, pub_test2; - -- Tests for partitioned tables SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_forparted; @@ -1199,51 +1004,32 @@ CREATE SCHEMA sch1; CREATE SCHEMA sch2; CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE(a); CREATE TABLE sch2.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) to (10); -CREATE SEQUENCE sch1.seq1; -CREATE SEQUENCE sch2.seq2; -- Schema publication that does not include the schema that has the parent table CREATE PUBLICATION pub FOR ALL TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=1); -ALTER PUBLICATION pub ADD ALL SEQUENCES IN SCHEMA sch2; SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; DROP PUBLICATION pub; -- Table publication that does not include the parent table CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=1); -ALTER PUBLICATION pub ADD SEQUENCE sch2.seq2; SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; -- Table publication that includes both the parent table and the child table ALTER PUBLICATION pub ADD TABLE sch1.tbl1; -ALTER PUBLICATION pub ADD SEQUENCE sch1.seq1; SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; DROP PUBLICATION pub; -- Schema publication that does not include the schema that has the parent table CREATE PUBLICATION pub FOR ALL TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=0); -ALTER PUBLICATION pub ADD SEQUENCE sch1.seq1; -SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; - -DROP PUBLICATION pub; --- Sequence publication -CREATE PUBLICATION pub FOR SEQUENCE sch2.seq2; SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; DROP PUBLICATION pub; -- Table publication that does not include the parent table CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=0); SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; -- Table publication that includes both the parent table and the child table ALTER PUBLICATION pub ADD TABLE sch1.tbl1; -ALTER PUBLICATION pub ADD ALL SEQUENCES IN SCHEMA sch2; SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; DROP PUBLICATION pub; DROP TABLE sch2.tbl1_part1; @@ -1256,36 +1042,10 @@ CREATE TABLE sch1.tbl1_part3 (a int) PARTITION BY RANGE(a); ALTER TABLE sch1.tbl1 ATTACH PARTITION sch1.tbl1_part3 FOR VALUES FROM (20) to (30); CREATE PUBLICATION pub FOR ALL TABLES IN SCHEMA sch1 WITH (PUBLISH_VIA_PARTITION_ROOT=1); SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; - -DROP PUBLICATION pub; --- Schema publication -CREATE PUBLICATION pub FOR SEQUENCE sch2.seq2; -SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; - -DROP PUBLICATION pub; --- Sequence publication -CREATE PUBLICATION pub FOR ALL SEQUENCES IN SCHEMA sch2; -SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; - -ALTER PUBLICATION pub ADD SEQUENCE sch1.seq1; -SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; - -ALTER PUBLICATION pub DROP SEQUENCE sch1.seq1; -SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; - -ALTER PUBLICATION pub ADD ALL SEQUENCES IN SCHEMA sch1; -SELECT * FROM pg_publication_tables; -SELECT * FROM pg_publication_sequences; RESET client_min_messages; DROP PUBLICATION pub; DROP TABLE sch1.tbl1; -DROP SEQUENCE sch1.seq1, sch2.seq2; DROP SCHEMA sch1 cascade; DROP SCHEMA sch2 cascade; diff --git a/src/test/subscription/t/030_sequences.pl b/src/test/subscription/t/030_sequences.pl deleted file mode 100644 index 9ae3c03d7d1..00000000000 --- a/src/test/subscription/t/030_sequences.pl +++ /dev/null @@ -1,202 +0,0 @@ - -# Copyright (c) 2021, PostgreSQL Global Development Group - -# This tests that sequences are replicated correctly by logical replication -use strict; -use warnings; -use PostgreSQL::Test::Cluster; -use PostgreSQL::Test::Utils; -use Test::More; - -# Initialize publisher node -my $node_publisher = PostgreSQL::Test::Cluster->new('publisher'); -$node_publisher->init(allows_streaming => 'logical'); -$node_publisher->start; - -# Create subscriber node -my $node_subscriber = PostgreSQL::Test::Cluster->new('subscriber'); -$node_subscriber->init(allows_streaming => 'logical'); -$node_subscriber->start; - -# Create some preexisting content on publisher -my $ddl = qq( - CREATE TABLE seq_test (v BIGINT); - CREATE SEQUENCE s; -); - -# Setup structure on the publisher -$node_publisher->safe_psql('postgres', $ddl); - -# Create some the same structure on subscriber, and an extra sequence that -# we'll create on the publisher later -$ddl = qq( - CREATE TABLE seq_test (v BIGINT); - CREATE SEQUENCE s; - CREATE SEQUENCE s2; -); - -$node_subscriber->safe_psql('postgres', $ddl); - -# Setup logical replication -my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; -$node_publisher->safe_psql('postgres', - "CREATE PUBLICATION seq_pub"); - -$node_publisher->safe_psql('postgres', - "ALTER PUBLICATION seq_pub ADD SEQUENCE s"); - -$node_subscriber->safe_psql('postgres', - "CREATE SUBSCRIPTION seq_sub CONNECTION '$publisher_connstr' PUBLICATION seq_pub" -); - -$node_publisher->wait_for_catchup('seq_sub'); - -# Wait for initial sync to finish as well -my $synced_query = - "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; -$node_subscriber->poll_query_until('postgres', $synced_query) - or die "Timed out while waiting for subscriber to synchronize data"; - -# Insert initial test data -$node_publisher->safe_psql( - 'postgres', qq( - -- generate a number of values using the sequence - INSERT INTO seq_test SELECT nextval('s') FROM generate_series(1,100); -)); - -$node_publisher->wait_for_catchup('seq_sub'); - -# Check the data on subscriber -my $result = $node_subscriber->safe_psql( - 'postgres', qq( - SELECT * FROM s; -)); - -is( $result, '132|0|t', - 'initial test data replicated'); - - -# advance the sequence in a rolled-back transaction - the rollback -# does not wait for the replication, so we could see any intermediate state -# so do something else after the test, to ensure we wait for everything -$node_publisher->safe_psql( - 'postgres', qq( - BEGIN; - INSERT INTO seq_test SELECT nextval('s') FROM generate_series(1,100); - ROLLBACK; - INSERT INTO seq_test VALUES (-1); -)); - -$node_publisher->wait_for_catchup('seq_sub'); - -# Check the data on subscriber -$result = $node_subscriber->safe_psql( - 'postgres', qq( - SELECT * FROM s; -)); - -is( $result, '231|0|t', - 'advance sequence in rolled-back transaction'); - - -# create a new sequence and roll it back - should not be replicated, due to -# the transactional behavior -$node_publisher->safe_psql( - 'postgres', qq( - BEGIN; - CREATE SEQUENCE s2; - ALTER PUBLICATION seq_pub ADD SEQUENCE s2; - INSERT INTO seq_test SELECT nextval('s2') FROM generate_series(1,100); - ROLLBACK; -)); - -$node_publisher->wait_for_catchup('seq_sub'); - -# Check the data on subscriber -$result = $node_subscriber->safe_psql( - 'postgres', qq( - SELECT * FROM s2; -)); - -is( $result, '1|0|f', - 'create new sequence and roll it back'); - - -# create a new sequence, advance it in a rolled-back transaction, but commit -# the create - the advance should be replicated nevertheless -$node_publisher->safe_psql( - 'postgres', qq( - BEGIN; - CREATE SEQUENCE s2; - ALTER PUBLICATION seq_pub ADD SEQUENCE s2; - SAVEPOINT sp1; - INSERT INTO seq_test SELECT nextval('s2') FROM generate_series(1,100); - ROLLBACK TO sp1; - COMMIT; -)); - -$node_publisher->wait_for_catchup('seq_sub'); - -# Wait for sync of the second sequence we just added to finish -$synced_query = - "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; -$node_subscriber->poll_query_until('postgres', $synced_query) - or die "Timed out while waiting for subscriber to synchronize data"; - -# Check the data on subscriber -$result = $node_subscriber->safe_psql( - 'postgres', qq( - SELECT * FROM s2; -)); - -is( $result, '132|0|t', - 'create sequence, advance it in rolled-back transaction, but commit the create'); - - -# advance the new sequence in a transaction, and roll it back - the rollback -# does not wait for the replication, so we could see any intermediate state -# so do something else after the test, to ensure we wait for everything -$node_publisher->safe_psql( - 'postgres', qq( - BEGIN; - INSERT INTO seq_test SELECT nextval('s2') FROM generate_series(1,100); - ROLLBACK; - INSERT INTO seq_test VALUES (-1); -)); - -$node_publisher->wait_for_catchup('seq_sub'); - -# Check the data on subscriber -$result = $node_subscriber->safe_psql( - 'postgres', qq( - SELECT * FROM s2; -)); - -is( $result, '231|0|t', - 'advance the new sequence in a transaction and roll it back'); - - -# advance the sequence in a subtransaction - the subtransaction gets rolled -# back, but commit the main one - the changes should still be replicated -$node_publisher->safe_psql( - 'postgres', qq( - BEGIN; - SAVEPOINT s1; - INSERT INTO seq_test SELECT nextval('s2') FROM generate_series(1,100); - ROLLBACK TO s1; - COMMIT; -)); - -$node_publisher->wait_for_catchup('seq_sub'); - -# Check the data on subscriber -$result = $node_subscriber->safe_psql( - 'postgres', qq( - SELECT * FROM s2; -)); - -is( $result, '330|0|t', - 'advance sequence in a subtransaction'); - - -done_testing(); |