1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-26 01:22:12 +03:00

Fix the misuse of origin filter across multiple pg_logical_slot_get_changes() calls.

The pgoutput module uses a global variable (publish_no_origin) to cache
the action for the origin filter, but we didn't reset the flag when
shutting down the output plugin, so subsequent retries may access the
previous publish_no_origin value.

We fix this by storing the flag in the output plugin's private data.
Additionally, the patch removes the currently unused origin string from the
structure.

For the back branch, to avoid changing the exposed structure, we eliminated the
global variable and instead directly used the origin string for change
filtering.

Author: Hou Zhijie
Reviewed-by: Amit Kapila, Michael Paquier
Backpatch-through: 16
Discussion: http://postgr.es/m/OS0PR01MB571690EF24F51F51EFFCBB0E94FAA@OS0PR01MB5716.jpnprd01.prod.outlook.com
This commit is contained in:
Amit Kapila
2023-09-27 14:32:51 +05:30
parent 6fc3a138b1
commit 54ccfd6586
4 changed files with 90 additions and 9 deletions

View File

@ -82,7 +82,6 @@ static void pgoutput_stream_prepare_txn(LogicalDecodingContext *ctx,
static bool publications_valid;
static bool in_streaming;
static bool publish_no_origin;
static List *LoadPublications(List *pubnames);
static void publication_invalidation_cb(Datum arg, int cacheid,
@ -381,21 +380,23 @@ parse_output_parameters(List *options, PGOutputData *data)
}
else if (strcmp(defel->defname, "origin") == 0)
{
char *origin;
if (origin_option_given)
ereport(ERROR,
errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options"));
origin_option_given = true;
data->origin = defGetString(defel);
if (pg_strcasecmp(data->origin, LOGICALREP_ORIGIN_NONE) == 0)
publish_no_origin = true;
else if (pg_strcasecmp(data->origin, LOGICALREP_ORIGIN_ANY) == 0)
publish_no_origin = false;
origin = defGetString(defel);
if (pg_strcasecmp(origin, LOGICALREP_ORIGIN_NONE) == 0)
data->publish_no_origin = true;
else if (pg_strcasecmp(origin, LOGICALREP_ORIGIN_ANY) == 0)
data->publish_no_origin = false;
else
ereport(ERROR,
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized origin value: \"%s\"", data->origin));
errmsg("unrecognized origin value: \"%s\"", origin));
}
else
elog(ERROR, "unrecognized pgoutput option: %s", defel->defname);
@ -1673,7 +1674,9 @@ static bool
pgoutput_origin_filter(LogicalDecodingContext *ctx,
RepOriginId origin_id)
{
if (publish_no_origin && origin_id != InvalidRepOriginId)
PGOutputData *data = (PGOutputData *) ctx->output_plugin_private;
if (data->publish_no_origin && origin_id != InvalidRepOriginId)
return true;
return false;