Skip to content

Commit e65dbc9

Browse files
author
Amit Kapila
committed
Change publication's publish_generated_columns option type to enum.
The current boolean publish_generated_columns option only supports a binary choice, which is insufficient for future enhancements where generated columns can be of different types (e.g., stored or virtual). The supported values for the publish_generated_columns option are 'none' and 'stored'. Author: Vignesh C <vignesh21@gmail.com> Reviewed-by: Peter Smith <smithpb2250@gmail.com> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Discussion: https://postgr.es/m/d718d219-dd47-4a33-bb97-56e8fc4da994@eisentraut.org Discussion: https://postgr.es/m/B80D17B2-2C8E-4C7D-87F2-E5B4BE3C069E@gmail.com
1 parent eef4a33 commit e65dbc9

File tree

19 files changed

+394
-230
lines changed

19 files changed

+394
-230
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6394,6 +6394,20 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
63946394
</para></entry>
63956395
</row>
63966396

6397+
<row>
6398+
<entry role="catalog_table_entry"><para role="column_definition">
6399+
<structfield>pubgencols</structfield> <type>char</type>
6400+
</para>
6401+
<para>
6402+
Controls how to handle generated column replication when there is no
6403+
publication column list:
6404+
<literal>n</literal> = generated columns in the tables associated with
6405+
the publication should not be replicated,
6406+
<literal>s</literal> = stored generated columns in the tables associated
6407+
with the publication should be replicated.
6408+
</para></entry>
6409+
</row>
6410+
63976411
<row>
63986412
<entry role="catalog_table_entry"><para role="column_definition">
63996413
<structfield>pubviaroot</structfield> <type>bool</type>

doc/src/sgml/ref/create_publication.sgml

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
8989

9090
<para>
9191
When a column list is specified, only the named columns are replicated.
92-
The column list can contain generated columns as well. If no column list
93-
is specified, all table columns (except generated columns) are replicated
94-
through this publication, including any columns added later. It has no
95-
effect on <literal>TRUNCATE</literal> commands. See
92+
The column list can contain stored generated columns as well. If no
93+
column list is specified, all table columns (except generated columns)
94+
are replicated through this publication, including any columns added
95+
later. It has no effect on <literal>TRUNCATE</literal> commands. See
9696
<xref linkend="logical-replication-col-lists"/> for details about column
9797
lists.
9898
</para>
@@ -190,20 +190,31 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
190190
</varlistentry>
191191

192192
<varlistentry id="sql-createpublication-params-with-publish-generated-columns">
193-
<term><literal>publish_generated_columns</literal> (<type>boolean</type>)</term>
193+
<term><literal>publish_generated_columns</literal> (<type>enum</type>)</term>
194194
<listitem>
195195
<para>
196196
Specifies whether the generated columns present in the tables
197-
associated with the publication should be replicated.
198-
The default is <literal>false</literal>.
197+
associated with the publication should be replicated. Possible values
198+
are <literal>none</literal> and <literal>stored</literal>.
199+
</para>
200+
201+
<para>
202+
The default is <literal>none</literal> meaning the generated
203+
columns present in the tables associated with publication will not be
204+
replicated.
205+
</para>
206+
207+
<para>
208+
If set to <literal>stored</literal>, the stored generated columns
209+
present in the tables associated with publication will be replicated.
199210
</para>
200211

201212
<note>
202213
<para>
203214
If the subscriber is from a release prior to 18, then initial table
204215
synchronization won't copy generated columns even if parameter
205-
<literal>publish_generated_columns</literal> is true in the
206-
publisher.
216+
<literal>publish_generated_columns</literal> is <literal>stored</literal>
217+
in the publisher.
207218
</para>
208219
</note>
209220
</listitem>

src/backend/catalog/pg_publication.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -622,10 +622,11 @@ pub_collist_to_bitmapset(Bitmapset *columns, Datum pubcols, MemoryContext mcxt)
622622
/*
623623
* Returns a bitmap representing the columns of the specified table.
624624
*
625-
* Generated columns are included if include_gencols is true.
625+
* Generated columns are included if include_gencols_type is
626+
* PUBLISH_GENCOLS_STORED.
626627
*/
627628
Bitmapset *
628-
pub_form_cols_map(Relation relation, bool include_gencols)
629+
pub_form_cols_map(Relation relation, PublishGencolsType include_gencols_type)
629630
{
630631
Bitmapset *result = NULL;
631632
TupleDesc desc = RelationGetDescr(relation);
@@ -634,9 +635,20 @@ pub_form_cols_map(Relation relation, bool include_gencols)
634635
{
635636
Form_pg_attribute att = TupleDescAttr(desc, i);
636637

637-
if (att->attisdropped || (att->attgenerated && !include_gencols))
638+
if (att->attisdropped)
638639
continue;
639640

641+
if (att->attgenerated)
642+
{
643+
/* We only support replication of STORED generated cols. */
644+
if (att->attgenerated != ATTRIBUTE_GENERATED_STORED)
645+
continue;
646+
647+
/* User hasn't requested to replicate STORED generated cols. */
648+
if (include_gencols_type != PUBLISH_GENCOLS_STORED)
649+
continue;
650+
}
651+
640652
result = bms_add_member(result, att->attnum);
641653
}
642654

@@ -1068,7 +1080,7 @@ GetPublication(Oid pubid)
10681080
pub->pubactions.pubdelete = pubform->pubdelete;
10691081
pub->pubactions.pubtruncate = pubform->pubtruncate;
10701082
pub->pubviaroot = pubform->pubviaroot;
1071-
pub->pubgencols = pubform->pubgencols;
1083+
pub->pubgencols_type = pubform->pubgencols_type;
10721084

10731085
ReleaseSysCache(tup);
10741086

@@ -1276,9 +1288,23 @@ pg_get_publication_tables(PG_FUNCTION_ARGS)
12761288
{
12771289
Form_pg_attribute att = TupleDescAttr(desc, i);
12781290

1279-
if (att->attisdropped || (att->attgenerated && !pub->pubgencols))
1291+
if (att->attisdropped)
12801292
continue;
12811293

1294+
if (att->attgenerated)
1295+
{
1296+
/* We only support replication of STORED generated cols. */
1297+
if (att->attgenerated != ATTRIBUTE_GENERATED_STORED)
1298+
continue;
1299+
1300+
/*
1301+
* User hasn't requested to replicate STORED generated
1302+
* cols.
1303+
*/
1304+
if (pub->pubgencols_type != PUBLISH_GENCOLS_STORED)
1305+
continue;
1306+
}
1307+
12821308
attnums[nattnums++] = att->attnum;
12831309
}
12841310

src/backend/commands/publicationcmds.c

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static void PublicationDropTables(Oid pubid, List *rels, bool missing_ok);
7070
static void PublicationAddSchemas(Oid pubid, List *schemas, bool if_not_exists,
7171
AlterPublicationStmt *stmt);
7272
static void PublicationDropSchemas(Oid pubid, List *schemas, bool missing_ok);
73+
static char defGetGeneratedColsOption(DefElem *def);
7374

7475

7576
static void
@@ -80,7 +81,7 @@ parse_publication_options(ParseState *pstate,
8081
bool *publish_via_partition_root_given,
8182
bool *publish_via_partition_root,
8283
bool *publish_generated_columns_given,
83-
bool *publish_generated_columns)
84+
char *publish_generated_columns)
8485
{
8586
ListCell *lc;
8687

@@ -94,7 +95,7 @@ parse_publication_options(ParseState *pstate,
9495
pubactions->pubdelete = true;
9596
pubactions->pubtruncate = true;
9697
*publish_via_partition_root = false;
97-
*publish_generated_columns = false;
98+
*publish_generated_columns = PUBLISH_GENCOLS_NONE;
9899

99100
/* Parse options */
100101
foreach(lc, options)
@@ -160,7 +161,7 @@ parse_publication_options(ParseState *pstate,
160161
if (*publish_generated_columns_given)
161162
errorConflictingDefElem(defel, pstate);
162163
*publish_generated_columns_given = true;
163-
*publish_generated_columns = defGetBoolean(defel);
164+
*publish_generated_columns = defGetGeneratedColsOption(defel);
164165
}
165166
else
166167
ereport(ERROR,
@@ -344,15 +345,16 @@ pub_rf_contains_invalid_column(Oid pubid, Relation relation, List *ancestors,
344345
* by the column list. If any column is missing, *invalid_column_list is set
345346
* to true.
346347
* 2. Ensures that all the generated columns referenced in the REPLICA IDENTITY
347-
* are published either by listing them in the column list or by enabling
348-
* publish_generated_columns option. If any unpublished generated column is
349-
* found, *invalid_gen_col is set to true.
348+
* are published, either by being explicitly named in the column list or, if
349+
* no column list is specified, by setting the option
350+
* publish_generated_columns to stored. If any unpublished
351+
* generated column is found, *invalid_gen_col is set to true.
350352
*
351353
* Returns true if any of the above conditions are not met.
352354
*/
353355
bool
354356
pub_contains_invalid_column(Oid pubid, Relation relation, List *ancestors,
355-
bool pubviaroot, bool pubgencols,
357+
bool pubviaroot, char pubgencols_type,
356358
bool *invalid_column_list,
357359
bool *invalid_gen_col)
358360
{
@@ -394,10 +396,10 @@ pub_contains_invalid_column(Oid pubid, Relation relation, List *ancestors,
394396

395397
/*
396398
* As we don't allow a column list with REPLICA IDENTITY FULL, the
397-
* publish_generated_columns option must be set to true if the table
399+
* publish_generated_columns option must be set to stored if the table
398400
* has any stored generated columns.
399401
*/
400-
if (!pubgencols &&
402+
if (pubgencols_type != PUBLISH_GENCOLS_STORED &&
401403
relation->rd_att->constr &&
402404
relation->rd_att->constr->has_generated_stored)
403405
*invalid_gen_col = true;
@@ -425,10 +427,10 @@ pub_contains_invalid_column(Oid pubid, Relation relation, List *ancestors,
425427
if (columns == NULL)
426428
{
427429
/*
428-
* The publish_generated_columns option must be set to true if the
429-
* REPLICA IDENTITY contains any stored generated column.
430+
* The publish_generated_columns option must be set to stored if
431+
* the REPLICA IDENTITY contains any stored generated column.
430432
*/
431-
if (!pubgencols && att->attgenerated)
433+
if (pubgencols_type != PUBLISH_GENCOLS_STORED && att->attgenerated)
432434
{
433435
*invalid_gen_col = true;
434436
break;
@@ -775,7 +777,7 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
775777
bool publish_via_partition_root_given;
776778
bool publish_via_partition_root;
777779
bool publish_generated_columns_given;
778-
bool publish_generated_columns;
780+
char publish_generated_columns;
779781
AclResult aclresult;
780782
List *relations = NIL;
781783
List *schemaidlist = NIL;
@@ -834,8 +836,8 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
834836
BoolGetDatum(pubactions.pubtruncate);
835837
values[Anum_pg_publication_pubviaroot - 1] =
836838
BoolGetDatum(publish_via_partition_root);
837-
values[Anum_pg_publication_pubgencols - 1] =
838-
BoolGetDatum(publish_generated_columns);
839+
values[Anum_pg_publication_pubgencols_type - 1] =
840+
CharGetDatum(publish_generated_columns);
839841

840842
tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
841843

@@ -922,7 +924,7 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt,
922924
bool publish_via_partition_root_given;
923925
bool publish_via_partition_root;
924926
bool publish_generated_columns_given;
925-
bool publish_generated_columns;
927+
char publish_generated_columns;
926928
ObjectAddress obj;
927929
Form_pg_publication pubform;
928930
List *root_relids = NIL;
@@ -1046,8 +1048,8 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt,
10461048

10471049
if (publish_generated_columns_given)
10481050
{
1049-
values[Anum_pg_publication_pubgencols - 1] = BoolGetDatum(publish_generated_columns);
1050-
replaces[Anum_pg_publication_pubgencols - 1] = true;
1051+
values[Anum_pg_publication_pubgencols_type - 1] = CharGetDatum(publish_generated_columns);
1052+
replaces[Anum_pg_publication_pubgencols_type - 1] = true;
10511053
}
10521054

10531055
tup = heap_modify_tuple(tup, RelationGetDescr(rel), values, nulls,
@@ -2043,3 +2045,33 @@ AlterPublicationOwner_oid(Oid subid, Oid newOwnerId)
20432045

20442046
table_close(rel, RowExclusiveLock);
20452047
}
2048+
2049+
/*
2050+
* Extract the publish_generated_columns option value from a DefElem. "stored"
2051+
* and "none" values are accepted.
2052+
*/
2053+
static char
2054+
defGetGeneratedColsOption(DefElem *def)
2055+
{
2056+
char *sval;
2057+
2058+
/*
2059+
* If no parameter value given, assume "stored" is meant.
2060+
*/
2061+
if (!def->arg)
2062+
return PUBLISH_GENCOLS_STORED;
2063+
2064+
sval = defGetString(def);
2065+
2066+
if (pg_strcasecmp(sval, "none") == 0)
2067+
return PUBLISH_GENCOLS_NONE;
2068+
if (pg_strcasecmp(sval, "stored") == 0)
2069+
return PUBLISH_GENCOLS_STORED;
2070+
2071+
ereport(ERROR,
2072+
errcode(ERRCODE_SYNTAX_ERROR),
2073+
errmsg("%s requires a \"none\" or \"stored\" value",
2074+
def->defname));
2075+
2076+
return PUBLISH_GENCOLS_NONE; /* keep compiler quiet */
2077+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy