Compare commits

...

12 Commits

Author SHA1 Message Date
Alexander Korotkov
e0477837ce Make replace_relid() leave argument unmodified
There are a lot of situations when we share the same pointer to a Bitmapset
structure across different places.  In order to evade undesirable side effects
replace_relid() function should always return a copy.

Reported-by: Richard Guo
Discussion: https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.com
Reviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
2023-12-27 03:57:57 +02:00
Alexander Korotkov
7d58f2342b REALLOCATE_BITMAPSETS manual compile-time option
This option forces each bitmapset modification to reallocate bitmapset.  This
is useful for debugging hangling pointers to bitmapset's.

Discussion: https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.com
Reviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
2023-12-27 03:57:57 +02:00
Alexander Korotkov
71a3e8c43b Add asserts to bimapset manipulation functions
New asserts validate that arguments are really bitmapsets.  This should help
to early detect accesses to dangling pointers.

Discussion: https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.com
Reviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
2023-12-27 03:57:57 +02:00
Tom Lane
059de3ca47 Fix failure to verify PGC_[SU_]BACKEND GUCs in pg_file_settings view.
set_config_option() bails out early if it detects that the option to
be set is PGC_BACKEND or PGC_SU_BACKEND class and we're reading the
config file in a postmaster child; we don't want to apply any new
value in such a case.  That's fine as far as it goes, but it fails
to consider the requirements of the pg_file_settings view: for that,
we need to check validity of the value even though we have no
intention to apply it.  Because we didn't, even very silly values
for affected GUCs would be reported as valid by the view.  There
are only half a dozen such GUCs, which perhaps explains why this
got overlooked for so long.

Fix by continuing when changeVal is false; this parallels the logic
in some other early-exit paths.

Also, the check added by commit 924bcf4f1 to prevent GUC changes in
parallel workers seems a few bricks shy of a load: it's evidently
assuming that ereport(elevel, ...) won't return.  Make sure we
bail out if it does.  The lack of trouble reports suggests that
this is only a latent bug, i.e. parallel workers don't actually
reach here with elevel < ERROR.  (Per the code coverage report,
we never reach here at all in the regression suite.)  But we clearly
don't want to risk proceeding if that does happen.

Per report from Rıdvan Korkmaz.  These are ancient bugs, so back-patch
to all supported branches.

Discussion: https://postgr.es/m/2089235.1703617353@sss.pgh.pa.us
2023-12-26 17:57:48 -05:00
Tom Lane
a46972e30c Fix mistaken file name in plpython's meson recipe.
Brown-paper-bag bug in commit 58c3151bb.  Per buildfarm.
2023-12-26 17:03:02 -05:00
Tom Lane
58c3151bbc Hide warnings from Python headers when using gcc-compatible compiler.
Like commit 388e80132, use "#pragma GCC system_header" to silence
warnings appearing within the Python headers, since newer Python
versions no longer worry about some restrictions we still use like
-Wdeclaration-after-statement.

This patch improves on 388e80132 by inventing a separate wrapper
header file, allowing the pragma to be tightly scoped to just
the Python headers and not other stuff we have laying about in
plpython.h.  I applied the same technique to plperl for the same
reason: the original patch suppressed warnings for a good deal
of our own code, not only the Perl headers.

Like the previous commit, back-patch to supported branches.

Peter Eisentraut and Tom Lane

Discussion: https://postgr.es/m/ae523163-6d2a-4b81-a875-832e48dec502@eisentraut.org
2023-12-26 16:16:37 -05:00
Peter Eisentraut
c4fe2e8220 Add meson NLS support for pg_combinebackup 2023-12-26 21:33:57 +01:00
Bruce Momjian
f67a3d4268 doc: add ISO 8601 extended format example using to_char()
Reported-by: juha.mustonen@iki.fi

Discussion: https://postgr.es/m/20170217160154.6101.52806@wrigleys.postgresql.org

Co-authored-by: Erik Wienhold

Backpatch-through: master
2023-12-26 15:31:50 -05:00
Tom Lane
bbf1f13408 Add empty placeholder LINGUAS file for pg_combinebackup.
This will eventually be replaced once some translations exist
for pg_combinebackup's messages.  In the meantime, we need
something here to prevent "make" from complaining in
builds with --enable-nls.  Per advice added in 88dad06b4.
2023-12-26 14:37:46 -05:00
Peter Eisentraut
d327f418d1 Remove unused macro
Usage was removed in 6c5576075b but the definition was not removed.
2023-12-26 20:13:11 +01:00
Michael Paquier
231ff70f98 Fix some translatable strings in pg_basebackup and pg_combinebackup
Two translatable strings introduced in dc212340058b were split into two
parts, making their translation harder than necessary.

Author: Kyotaro Horiguchi
Discussion: https://postgr.es/m/20231225.134747.2287499067164862136.horikyota.ntt@gmail.com
2023-12-26 18:54:36 +09:00
Amit Kapila
0eac3c798c Doc: Add missing pgoutput options.
We forgot to update the docs while adding new options in pgoutput.

Author: Emre Hasegeli
Reviewed-by: Peter Smith, Amit Kapila
Backpatch-through: 12
Discussion: https://postgr.es/m/CAE2gYzwdwtUbs-tPSV-QBwgTubiyGD2ZGsSnAVsDfAGGLDrGOA%40mail.gmail.com
2023-12-26 10:31:50 +05:30
23 changed files with 562 additions and 245 deletions

View File

@ -8748,6 +8748,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
<entry><literal>to_char(current_timestamp, 'FMDay,&nbsp;FMDD&nbsp;&nbsp;HH12:MI:SS')</literal></entry>
<entry><literal>'Tuesday,&nbsp;6&nbsp;&nbsp;05:39:18'</literal></entry>
</row>
<row>
<entry><literal>to_char(current_timestamp AT TIME ZONE
'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')</literal></entry>
<entry><literal>'2022-12-06T05:39:18Z'</literal>,
<acronym>ISO</acronym> 8601 extended format</entry>
</row>
<row>
<entry><literal>to_char(-0.1, '99.99')</literal></entry>
<entry><literal>'&nbsp;&nbsp;-.10'</literal></entry>

View File

@ -535,7 +535,7 @@ test_sub=# SELECT * FROM t3;
remote replication slot was not created automatically, the user must create
it manually before the subscription can be activated. The steps to create
the slot and activate the subscription are shown in the following examples.
These examples specify the standard logical decoding plugin
These examples specify the standard logical decoding output plugin
(<literal>pgoutput</literal>), which is what the built-in logical
replication uses.
</para>
@ -1662,7 +1662,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER
implemented by <literal>walsender</literal> and <literal>apply</literal>
processes. The walsender process starts logical decoding (described
in <xref linkend="logicaldecoding"/>) of the WAL and loads the standard
logical decoding plugin (pgoutput). The plugin transforms the changes read
logical decoding output plugin (<literal>pgoutput</literal>). The plugin
transforms the changes read
from WAL to the logical replication protocol
(see <xref linkend="protocol-logical-replication"/>) and filters the data
according to the publication specification. The data is then continuously

View File

@ -2545,7 +2545,10 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
<term><replaceable class="parameter">option_name</replaceable></term>
<listitem>
<para>
The name of an option passed to the slot's logical decoding plugin.
The name of an option passed to the slot's logical decoding output
plugin. See <xref linkend="protocol-logical-replication"/> for
options that are accepted by the standard (<literal>pgoutput</literal>)
plugin.
</para>
</listitem>
</varlistentry>
@ -3106,12 +3109,18 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
the physical streaming replication protocol.
</para>
<para>
<productname>PostgreSQL</productname> logical decoding supports output
plugins. <literal>pgoutput</literal> is the standard one used for
the built-in logical replication.
</para>
<sect2 id="protocol-logical-replication-params">
<title>Logical Streaming Replication Parameters</title>
<para>
The logical replication <literal>START_REPLICATION</literal> command
accepts following parameters:
Using the <literal>START_REPLICATION</literal> command,
<literal>pgoutput</literal> accepts the following options:
<variablelist>
<varlistentry>
@ -3121,7 +3130,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
<listitem>
<para>
Protocol version. Currently versions <literal>1</literal>, <literal>2</literal>,
<literal>3</literal>, and <literal>4</literal> are supported.
<literal>3</literal>, and <literal>4</literal> are supported. A valid
version is required.
</para>
<para>
Version <literal>2</literal> is supported only for server version 14
@ -3148,6 +3158,73 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
Comma separated list of publication names for which to subscribe
(receive changes). The individual publication names are treated
as standard objects names and can be quoted the same as needed.
At least one publication name is required.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
binary
</term>
<listitem>
<para>
Boolean option to use binary transfer mode. Binary mode is faster
than the text mode but slightly less robust.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
messages
</term>
<listitem>
<para>
Boolean option to enable sending the messages that are written
by <function>pg_logical_emit_message</function>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
streaming
</term>
<listitem>
<para>
Boolean option to enable streaming of in-progress transactions.
It accepts an additional value "parallel" to enable sending extra
information with some messages to be used for parallelisation.
Minimum protocol version 2 is required to turn it on. Minimum protocol
version 4 is required for the "parallel" option.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
two_phase
</term>
<listitem>
<para>
Boolean option to enable two-phase transactions. Minimum protocol
version 3 is required to turn it on.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
origin
</term>
<listitem>
<para>
Option to send changes by their origin. Possible values are "none"
to only send the changes that have no origin associated, or "any"
to send the changes regardless of their origin. This can be used
to avoid loops (infinite replication of the same data) among
replication nodes.
</para>
</listitem>
</varlistentry>

View File

@ -84,6 +84,7 @@ bms_copy(const Bitmapset *a)
if (a == NULL)
return NULL;
Assert(IsA(a, Bitmapset));
size = BITMAPSET_SIZE(a->nwords);
result = (Bitmapset *) palloc(size);
memcpy(result, a, size);
@ -98,8 +99,8 @@ bms_equal(const Bitmapset *a, const Bitmapset *b)
{
int i;
Assert(a == NULL || a->words[a->nwords - 1] != 0);
Assert(b == NULL || b->words[b->nwords - 1] != 0);
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@ -139,8 +140,8 @@ bms_compare(const Bitmapset *a, const Bitmapset *b)
{
int i;
Assert(a == NULL || a->words[a->nwords - 1] != 0);
Assert(b == NULL || b->words[b->nwords - 1] != 0);
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@ -215,6 +216,9 @@ bms_union(const Bitmapset *a, const Bitmapset *b)
int otherlen;
int i;
Assert(a == NULL || IsA(a, Bitmapset));
Assert(b == NULL || IsA(b, Bitmapset));
/* Handle cases where either input is NULL */
if (a == NULL)
return bms_copy(b);
@ -253,9 +257,13 @@ bms_intersect(const Bitmapset *a, const Bitmapset *b)
int resultlen;
int i;
Assert(a == NULL || IsA(a, Bitmapset));
Assert(b == NULL || IsA(b, Bitmapset));
/* Handle cases where either input is NULL */
if (a == NULL || b == NULL)
return NULL;
/* Identify shorter and longer input; copy the shorter one */
if (a->nwords <= b->nwords)
{
@ -299,8 +307,8 @@ bms_difference(const Bitmapset *a, const Bitmapset *b)
Bitmapset *result;
int i;
Assert(a == NULL || a->words[a->nwords - 1] != 0);
Assert(b == NULL || b->words[b->nwords - 1] != 0);
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@ -308,6 +316,8 @@ bms_difference(const Bitmapset *a, const Bitmapset *b)
if (b == NULL)
return bms_copy(a);
Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
/*
* In Postgres' usage, an empty result is a very common case, so it's
* worth optimizing for that by testing bms_nonempty_difference(). This
@ -364,8 +374,8 @@ bms_is_subset(const Bitmapset *a, const Bitmapset *b)
{
int i;
Assert(a == NULL || a->words[a->nwords - 1] != 0);
Assert(b == NULL || b->words[b->nwords - 1] != 0);
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@ -373,6 +383,8 @@ bms_is_subset(const Bitmapset *a, const Bitmapset *b)
if (b == NULL)
return false;
Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
/* 'a' can't be a subset of 'b' if it contains more words */
if (a->nwords > b->nwords)
return false;
@ -399,8 +411,8 @@ bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
int shortlen;
int i;
Assert(a == NULL || a->words[a->nwords - 1] != 0);
Assert(b == NULL || b->words[b->nwords - 1] != 0);
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@ -411,6 +423,9 @@ bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
}
if (b == NULL)
return BMS_SUBSET2;
Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
/* Check common words */
result = BMS_EQUAL; /* status so far */
shortlen = Min(a->nwords, b->nwords);
@ -467,6 +482,9 @@ bms_is_member(int x, const Bitmapset *a)
elog(ERROR, "negative bitmapset member not allowed");
if (a == NULL)
return false;
Assert(IsA(a, Bitmapset));
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
if (wordnum >= a->nwords)
@ -495,6 +513,8 @@ bms_member_index(Bitmapset *a, int x)
if (!bms_is_member(x, a))
return -1;
Assert(IsA(a, Bitmapset));
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
@ -529,6 +549,9 @@ bms_overlap(const Bitmapset *a, const Bitmapset *b)
int shortlen;
int i;
Assert(a == NULL || IsA(a, Bitmapset));
Assert(b == NULL || IsA(b, Bitmapset));
/* Handle cases where either input is NULL */
if (a == NULL || b == NULL)
return false;
@ -553,6 +576,8 @@ bms_overlap_list(const Bitmapset *a, const List *b)
int wordnum,
bitnum;
Assert(a == NULL || IsA(a, Bitmapset));
if (a == NULL || b == NIL)
return false;
@ -582,8 +607,8 @@ bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
{
int i;
Assert(a == NULL || a->words[a->nwords - 1] != 0);
Assert(b == NULL || b->words[b->nwords - 1] != 0);
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@ -617,6 +642,9 @@ bms_singleton_member(const Bitmapset *a)
if (a == NULL)
elog(ERROR, "bitmapset is empty");
Assert(IsA(a, Bitmapset));
nwords = a->nwords;
wordnum = 0;
do
@ -657,6 +685,7 @@ bms_get_singleton_member(const Bitmapset *a, int *member)
if (a == NULL)
return false;
Assert(IsA(a, Bitmapset));
nwords = a->nwords;
wordnum = 0;
do
@ -690,6 +719,7 @@ bms_num_members(const Bitmapset *a)
if (a == NULL)
return 0;
Assert(IsA(a, Bitmapset));
nwords = a->nwords;
wordnum = 0;
do
@ -717,6 +747,7 @@ bms_membership(const Bitmapset *a)
if (a == NULL)
return BMS_EMPTY_SET;
Assert(IsA(a, Bitmapset));
nwords = a->nwords;
wordnum = 0;
do
@ -759,6 +790,7 @@ bms_add_member(Bitmapset *a, int x)
elog(ERROR, "negative bitmapset member not allowed");
if (a == NULL)
return bms_make_singleton(x);
Assert(IsA(a, Bitmapset));
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
@ -767,8 +799,15 @@ bms_add_member(Bitmapset *a, int x)
{
int oldnwords = a->nwords;
int i;
#ifdef REALLOCATE_BITMAPSETS
Bitmapset *tmp = a;
a = (Bitmapset *) palloc(BITMAPSET_SIZE(wordnum + 1));
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
pfree(tmp);
#else
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(wordnum + 1));
#endif
a->nwords = wordnum + 1;
/* zero out the enlarged portion */
i = oldnwords;
@ -777,6 +816,16 @@ bms_add_member(Bitmapset *a, int x)
a->words[i] = 0;
} while (++i < a->nwords);
}
#ifdef REALLOCATE_BITMAPSETS
else
{
Bitmapset *tmp = a;
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
pfree(tmp);
}
#endif
a->words[wordnum] |= ((bitmapword) 1 << bitnum);
return a;
@ -794,14 +843,26 @@ bms_del_member(Bitmapset *a, int x)
{
int wordnum,
bitnum;
#ifdef REALLOCATE_BITMAPSETS
Bitmapset *tmp = a;
#endif
if (x < 0)
elog(ERROR, "negative bitmapset member not allowed");
if (a == NULL)
return NULL;
Assert(IsA(a, Bitmapset));
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
#ifdef REALLOCATE_BITMAPSETS
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
pfree(tmp);
#endif
/* member can't exist. Return 'a' unmodified */
if (unlikely(wordnum >= a->nwords))
return a;
@ -839,6 +900,9 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
int otherlen;
int i;
Assert(a == NULL || IsA(a, Bitmapset));
Assert(b == NULL || IsA(b, Bitmapset));
/* Handle cases where either input is NULL */
if (a == NULL)
return bms_copy(b);
@ -852,6 +916,13 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
}
else
{
#ifdef REALLOCATE_BITMAPSETS
Bitmapset *tmp = a;
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
pfree(tmp);
#endif
result = a;
other = b;
}
@ -884,6 +955,8 @@ bms_add_range(Bitmapset *a, int lower, int upper)
ushiftbits,
wordnum;
Assert(a == NULL || IsA(a, Bitmapset));
/* do nothing if nothing is called for, without further checking */
if (upper < lower)
return a;
@ -902,9 +975,16 @@ bms_add_range(Bitmapset *a, int lower, int upper)
{
int oldnwords = a->nwords;
int i;
#ifdef REALLOCATE_BITMAPSETS
Bitmapset *tmp = a;
a = (Bitmapset *) palloc(BITMAPSET_SIZE(uwordnum + 1));
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
pfree(tmp);
#else
/* ensure we have enough words to store the upper bit */
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(uwordnum + 1));
#endif
a->nwords = uwordnum + 1;
/* zero out the enlarged portion */
i = oldnwords;
@ -953,6 +1033,15 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
int lastnonzero;
int shortlen;
int i;
#ifdef REALLOCATE_BITMAPSETS
Bitmapset *tmp = a;
#endif
Assert(a == NULL || IsA(a, Bitmapset));
Assert(b == NULL || IsA(b, Bitmapset));
Assert(a == NULL || IsA(a, Bitmapset));
Assert(b == NULL || IsA(b, Bitmapset));
/* Handle cases where either input is NULL */
if (a == NULL)
@ -962,6 +1051,13 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
pfree(a);
return NULL;
}
#ifdef REALLOCATE_BITMAPSETS
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
pfree(tmp);
#endif
/* Intersect b into a; we need never copy */
shortlen = Min(a->nwords, b->nwords);
lastnonzero = -1;
@ -993,15 +1089,25 @@ Bitmapset *
bms_del_members(Bitmapset *a, const Bitmapset *b)
{
int i;
#ifdef REALLOCATE_BITMAPSETS
Bitmapset *tmp = a;
#endif
Assert(a == NULL || a->words[a->nwords - 1] != 0);
Assert(b == NULL || b->words[b->nwords - 1] != 0);
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
return NULL;
if (b == NULL)
return a;
#ifdef REALLOCATE_BITMAPSETS
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
pfree(tmp);
#endif
/* Remove b's bits from a; we need never copy */
if (a->nwords > b->nwords)
{
@ -1054,12 +1160,28 @@ bms_join(Bitmapset *a, Bitmapset *b)
Bitmapset *other;
int otherlen;
int i;
#ifdef REALLOCATE_BITMAPSETS
Bitmapset *tmp = a;
#endif
Assert(a == NULL || IsA(a, Bitmapset));
Assert(b == NULL || IsA(b, Bitmapset));
Assert(a == NULL || IsA(a, Bitmapset));
Assert(b == NULL || IsA(b, Bitmapset));
/* Handle cases where either input is NULL */
if (a == NULL)
return b;
if (b == NULL)
return a;
#ifdef REALLOCATE_BITMAPSETS
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
pfree(tmp);
#endif
/* Identify shorter and longer input; use longer one as result */
if (a->nwords < b->nwords)
{
@ -1109,6 +1231,8 @@ bms_next_member(const Bitmapset *a, int prevbit)
int wordnum;
bitmapword mask;
Assert(a == NULL || IsA(a, Bitmapset));
if (a == NULL)
return -2;
nwords = a->nwords;
@ -1168,6 +1292,8 @@ bms_prev_member(const Bitmapset *a, int prevbit)
int ushiftbits;
bitmapword mask;
Assert(a == NULL || IsA(a, Bitmapset));
/*
* If set is NULL or if there are no more bits to the right then we've
* nothing to do.

View File

@ -1522,6 +1522,10 @@ replace_varno_walker(Node *node, ReplaceVarnoContext *ctx)
/*
* Substitute newId by oldId in relids.
*
* We must make a copy of the original Bitmapset before making any
* modifications, because the same pointer to it might be shared among
* different places.
*/
static Bitmapset *
replace_relid(Relids relids, int oldId, int newId)
@ -1529,12 +1533,13 @@ replace_relid(Relids relids, int oldId, int newId)
if (oldId < 0)
return relids;
/* Delete relid without substitution. */
if (newId < 0)
/* Delete relid without substitution. */
return bms_del_member(relids, oldId);
return bms_del_member(bms_copy(relids), oldId);
/* Substitute newId for oldId. */
if (bms_is_member(oldId, relids))
return bms_add_member(bms_del_member(relids, oldId), newId);
return bms_add_member(bms_del_member(bms_copy(relids), oldId), newId);
return relids;
}

View File

@ -15,8 +15,6 @@
#include "fmgr.h"
#include "mb/pg_wchar.h"
#define ENCODING_GROWTH_RATE 4
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(euc_tw_to_big5);

View File

@ -3412,9 +3412,12 @@ set_config_with_handle(const char *name, config_handle *handle,
* Other changes might need to affect other workers, so forbid them.
*/
if (IsInParallelMode() && changeVal && action != GUC_ACTION_SAVE)
{
ereport(elevel,
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot set parameters during a parallel operation")));
return -1;
}
/* if handle is specified, no need to look up option */
if (!handle)
@ -3515,6 +3518,10 @@ set_config_with_handle(const char *name, config_handle *handle,
* backends. This is a tad klugy, but necessary because we
* don't re-read the config file during backend start.
*
* However, if changeVal is false then plow ahead anyway since
* we are trying to find out if the value is potentially good,
* not actually use it.
*
* In EXEC_BACKEND builds, this works differently: we load all
* non-default settings from the CONFIG_EXEC_PARAMS file
* during backend start. In that case we must accept
@ -3525,7 +3532,7 @@ set_config_with_handle(const char *name, config_handle *handle,
* started it. is_reload will be true when either situation
* applies.
*/
if (IsUnderPostmaster && !is_reload)
if (IsUnderPostmaster && changeVal && !is_reload)
return -1;
}
else if (context != PGC_POSTMASTER &&

View File

@ -396,8 +396,8 @@ usage(void)
printf(_("\nOptions controlling the output:\n"));
printf(_(" -D, --pgdata=DIRECTORY receive base backup into directory\n"));
printf(_(" -F, --format=p|t output format (plain (default), tar)\n"));
printf(_(" -i, --incremental=OLDMANIFEST\n"));
printf(_(" take incremental backup\n"));
printf(_(" -i, --incremental=OLDMANIFEST\n"
" take incremental backup\n"));
printf(_(" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
" (in kB/s, or use suffix \"k\" or \"M\")\n"));
printf(_(" -R, --write-recovery-conf\n"

View File

@ -36,3 +36,5 @@ tests += {
],
}
}
subdir('po', if_found: libintl)

View File

@ -669,8 +669,8 @@ help(const char *progname)
printf(_(" -n, --dry-run don't actually do anything\n"));
printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
printf(_(" -o, --output output directory\n"));
printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"));
printf(_(" relocate tablespace in OLDDIR to NEWDIR\n"));
printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
" relocate tablespace in OLDDIR to NEWDIR\n"));
printf(_(" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
" use algorithm for manifest checksums\n"));
printf(_(" --no-manifest suppress generation of backup manifest\n"));

View File

View File

@ -0,0 +1,3 @@
# Copyright (c) 2023, PostgreSQL Global Development Group
nls_targets += [i18n.gettext('pg_combinebackup-' + pg_version_major.to_string())]

View File

@ -335,6 +335,12 @@
*/
/* #define COPY_PARSE_PLAN_TREES */
/*
* Define this to force Bitmapset reallocation on each modification. Helps
* to find hangling pointers to Bitmapset's.
*/
/* #define REALLOCATE_BITMAPSETS */
/*
* Define this to force all parse and plan trees to be passed through
* outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in

View File

@ -108,11 +108,11 @@ uninstall: uninstall-lib uninstall-data
install-data: installdirs
$(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) '$(DESTDIR)$(datadir)/extension/'
$(INSTALL_DATA) $(srcdir)/plperl.h $(srcdir)/ppport.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) $(srcdir)/plperl.h $(srcdir)/plperl_system.h $(srcdir)/ppport.h '$(DESTDIR)$(includedir_server)'
uninstall-data:
rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, plperl.h ppport.h)
rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, plperl.h plperl_system.h ppport.h)
.PHONY: install-data uninstall-data

View File

@ -71,6 +71,7 @@ install_data(
install_headers(
'plperl.h',
'plperl_system.h',
'ppport.h',
install_dir: dir_include_server,
)

View File

@ -18,200 +18,11 @@
/* defines free() by way of system headers, so must be included before perl.h */
#include "mb/pg_wchar.h"
/* stop perl headers from hijacking stdio and other stuff on Windows */
#ifdef WIN32
#define WIN32IO_IS_STDIO
#endif /* WIN32 */
/*
* Supply a value of PERL_UNUSED_DECL that will satisfy gcc - the one
* perl itself supplies doesn't seem to.
* Pull in Perl headers via a wrapper header, to control the scope of
* the system_header pragma therein.
*/
#define PERL_UNUSED_DECL pg_attribute_unused()
/*
* Sometimes perl carefully scribbles on our *printf macros.
* So we undefine them here and redefine them after it's done its dirty deed.
*/
#undef vsnprintf
#undef snprintf
#undef vsprintf
#undef sprintf
#undef vfprintf
#undef fprintf
#undef vprintf
#undef printf
/*
* Perl scribbles on the "_" macro too.
*/
#undef _
/*
* ActivePerl 5.18 and later are MinGW-built, and their headers use GCC's
* __inline__. Translate to something MSVC recognizes. Also, perl.h sometimes
* defines isnan, so undefine it here and put back the definition later if
* perl.h doesn't.
*/
#ifdef _MSC_VER
#define __inline__ inline
#ifdef isnan
#undef isnan
#endif
/* Work around for using MSVC and Strawberry Perl >= 5.30. */
#define __builtin_expect(expr, val) (expr)
#endif
/*
* Regarding bool, both PostgreSQL and Perl might use stdbool.h or not,
* depending on configuration. If both agree, things are relatively harmless.
* If not, things get tricky. If PostgreSQL does but Perl does not, define
* HAS_BOOL here so that Perl does not redefine bool; this avoids compiler
* warnings. If PostgreSQL does not but Perl does, we need to undefine bool
* after we include the Perl headers; see below.
*/
#ifdef PG_USE_STDBOOL
#define HAS_BOOL 1
#endif
/*
* Newer versions of the perl headers trigger a lot of warnings with our
* compiler flags (at least -Wdeclaration-after-statement,
* -Wshadow=compatible-local are known to be problematic). The system_header
* pragma hides warnings from within the rest of this file, if supported.
*/
#ifdef HAVE_PRAGMA_GCC_SYSTEM_HEADER
#pragma GCC system_header
#endif
/*
* Get the basic Perl API. We use PERL_NO_GET_CONTEXT mode so that our code
* can compile against MULTIPLICITY Perl builds without including XSUB.h.
*/
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
/*
* We want to include XSUB.h only within .xs files, because on some platforms
* it undesirably redefines a lot of libc functions. But it must appear
* before ppport.h, so use a #define flag to control inclusion here.
*/
#ifdef PG_NEED_PERL_XSUB_H
/*
* On Windows, win32_port.h defines macros for a lot of these same functions.
* To avoid compiler warnings when XSUB.h redefines them, #undef our versions.
*/
#ifdef WIN32
#undef accept
#undef bind
#undef connect
#undef fopen
#undef fstat
#undef kill
#undef listen
#undef lstat
#undef mkdir
#undef open
#undef putenv
#undef recv
#undef rename
#undef select
#undef send
#undef socket
#undef stat
#undef unlink
#endif
#include "XSUB.h"
#endif
/* put back our *printf macros ... this must match src/include/port.h */
#ifdef vsnprintf
#undef vsnprintf
#endif
#ifdef snprintf
#undef snprintf
#endif
#ifdef vsprintf
#undef vsprintf
#endif
#ifdef sprintf
#undef sprintf
#endif
#ifdef vfprintf
#undef vfprintf
#endif
#ifdef fprintf
#undef fprintf
#endif
#ifdef vprintf
#undef vprintf
#endif
#ifdef printf
#undef printf
#endif
#define vsnprintf pg_vsnprintf
#define snprintf pg_snprintf
#define vsprintf pg_vsprintf
#define sprintf pg_sprintf
#define vfprintf pg_vfprintf
#define fprintf pg_fprintf
#define vprintf pg_vprintf
#define printf(...) pg_printf(__VA_ARGS__)
/*
* Put back "_" too; but rather than making it just gettext() as the core
* code does, make it dgettext() so that the right things will happen in
* loadable modules (if they've set up TEXTDOMAIN correctly). Note that
* we can't just set TEXTDOMAIN here, because this file is used by more
* extensions than just PL/Perl itself.
*/
#undef _
#define _(x) dgettext(TEXTDOMAIN, x)
/* put back the definition of isnan if needed */
#ifdef _MSC_VER
#ifndef isnan
#define isnan(x) _isnan(x)
#endif
#endif
/* perl version and platform portability */
#include "ppport.h"
/*
* perl might have included stdbool.h. If we also did that earlier (see c.h),
* then that's fine. If not, we probably rejected it for some reason. In
* that case, undef bool and proceed with our own bool. (Note that stdbool.h
* makes bool a macro, but our own replacement is a typedef, so the undef
* makes ours visible again).
*/
#ifndef PG_USE_STDBOOL
#ifdef bool
#undef bool
#endif
#endif
/* supply HeUTF8 if it's missing - ppport.h doesn't supply it, unfortunately */
#ifndef HeUTF8
#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \
SvUTF8(HeKEY_sv(he)) : \
(U32)HeKUTF8(he))
#endif
/* supply GvCV_set if it's missing - ppport.h doesn't supply it, unfortunately */
#ifndef GvCV_set
#define GvCV_set(gv, cv) (GvCV(gv) = cv)
#endif
/* Perl 5.19.4 changed array indices from I32 to SSize_t */
#if PERL_BCDVERSION >= 0x5019004
#define AV_SIZE_MAX SSize_t_MAX
#else
#define AV_SIZE_MAX I32_MAX
#endif
#include "plperl_system.h"
/* declare routines from plperl.c for access by .xs files */
HV *plperl_spi_exec(char *, int);

View File

@ -0,0 +1,215 @@
/*-------------------------------------------------------------------------
*
* plperl_system.h
* Pull in Perl's system header files.
*
* We break this out as a separate header file to precisely control
* the scope of the "system_header" pragma. No Postgres-specific
* declarations should be put here. However, we do include some stuff
* that is meant to prevent conflicts between our code and Perl.
*
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
* Portions Copyright (c) 1995, Regents of the University of California
*
* src/pl/plperl/plperl_system.h
*/
#ifndef PL_PERL_SYSTEM_H
#define PL_PERL_SYSTEM_H
/*
* Newer versions of the perl headers trigger a lot of warnings with our
* preferred compiler flags (at least -Wdeclaration-after-statement,
* -Wshadow=compatible-local are known to be problematic). The system_header
* pragma hides warnings from within the rest of this file, if supported.
*/
#ifdef HAVE_PRAGMA_GCC_SYSTEM_HEADER
#pragma GCC system_header
#endif
/* stop perl headers from hijacking stdio and other stuff on Windows */
#ifdef WIN32
#define WIN32IO_IS_STDIO
#endif /* WIN32 */
/*
* Supply a value of PERL_UNUSED_DECL that will satisfy gcc - the one
* perl itself supplies doesn't seem to.
*/
#define PERL_UNUSED_DECL pg_attribute_unused()
/*
* Sometimes perl carefully scribbles on our *printf macros.
* So we undefine them here and redefine them after it's done its dirty deed.
*/
#undef vsnprintf
#undef snprintf
#undef vsprintf
#undef sprintf
#undef vfprintf
#undef fprintf
#undef vprintf
#undef printf
/*
* Perl scribbles on the "_" macro too.
*/
#undef _
/*
* ActivePerl 5.18 and later are MinGW-built, and their headers use GCC's
* __inline__. Translate to something MSVC recognizes. Also, perl.h sometimes
* defines isnan, so undefine it here and put back the definition later if
* perl.h doesn't.
*/
#ifdef _MSC_VER
#define __inline__ inline
#ifdef isnan
#undef isnan
#endif
/* Work around for using MSVC and Strawberry Perl >= 5.30. */
#define __builtin_expect(expr, val) (expr)
#endif
/*
* Regarding bool, both PostgreSQL and Perl might use stdbool.h or not,
* depending on configuration. If both agree, things are relatively harmless.
* If not, things get tricky. If PostgreSQL does but Perl does not, define
* HAS_BOOL here so that Perl does not redefine bool; this avoids compiler
* warnings. If PostgreSQL does not but Perl does, we need to undefine bool
* after we include the Perl headers; see below.
*/
#ifdef PG_USE_STDBOOL
#define HAS_BOOL 1
#endif
/*
* Get the basic Perl API. We use PERL_NO_GET_CONTEXT mode so that our code
* can compile against MULTIPLICITY Perl builds without including XSUB.h.
*/
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
/*
* We want to include XSUB.h only within .xs files, because on some platforms
* it undesirably redefines a lot of libc functions. But it must appear
* before ppport.h, so use a #define flag to control inclusion here.
*/
#ifdef PG_NEED_PERL_XSUB_H
/*
* On Windows, win32_port.h defines macros for a lot of these same functions.
* To avoid compiler warnings when XSUB.h redefines them, #undef our versions.
*/
#ifdef WIN32
#undef accept
#undef bind
#undef connect
#undef fopen
#undef fstat
#undef kill
#undef listen
#undef lstat
#undef mkdir
#undef open
#undef putenv
#undef recv
#undef rename
#undef select
#undef send
#undef socket
#undef stat
#undef unlink
#endif
#include "XSUB.h"
#endif
/* put back our *printf macros ... this must match src/include/port.h */
#ifdef vsnprintf
#undef vsnprintf
#endif
#ifdef snprintf
#undef snprintf
#endif
#ifdef vsprintf
#undef vsprintf
#endif
#ifdef sprintf
#undef sprintf
#endif
#ifdef vfprintf
#undef vfprintf
#endif
#ifdef fprintf
#undef fprintf
#endif
#ifdef vprintf
#undef vprintf
#endif
#ifdef printf
#undef printf
#endif
#define vsnprintf pg_vsnprintf
#define snprintf pg_snprintf
#define vsprintf pg_vsprintf
#define sprintf pg_sprintf
#define vfprintf pg_vfprintf
#define fprintf pg_fprintf
#define vprintf pg_vprintf
#define printf(...) pg_printf(__VA_ARGS__)
/*
* Put back "_" too; but rather than making it just gettext() as the core
* code does, make it dgettext() so that the right things will happen in
* loadable modules (if they've set up TEXTDOMAIN correctly). Note that
* we can't just set TEXTDOMAIN here, because this file is used by more
* extensions than just PL/Perl itself.
*/
#undef _
#define _(x) dgettext(TEXTDOMAIN, x)
/* put back the definition of isnan if needed */
#ifdef _MSC_VER
#ifndef isnan
#define isnan(x) _isnan(x)
#endif
#endif
/* perl version and platform portability */
#include "ppport.h"
/*
* perl might have included stdbool.h. If we also did that earlier (see c.h),
* then that's fine. If not, we probably rejected it for some reason. In
* that case, undef bool and proceed with our own bool. (Note that stdbool.h
* makes bool a macro, but our own replacement is a typedef, so the undef
* makes ours visible again).
*/
#ifndef PG_USE_STDBOOL
#ifdef bool
#undef bool
#endif
#endif
/* supply HeUTF8 if it's missing - ppport.h doesn't supply it, unfortunately */
#ifndef HeUTF8
#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \
SvUTF8(HeKEY_sv(he)) : \
(U32)HeKUTF8(he))
#endif
/* supply GvCV_set if it's missing - ppport.h doesn't supply it, unfortunately */
#ifndef GvCV_set
#define GvCV_set(gv, cv) (GvCV(gv) = cv)
#endif
/* Perl 5.19.4 changed array indices from I32 to SSize_t */
#if PERL_BCDVERSION >= 0x5019004
#define AV_SIZE_MAX SSize_t_MAX
#else
#define AV_SIZE_MAX I32_MAX
#endif
#endif /* PL_PERL_SYSTEM_H */

View File

@ -39,6 +39,7 @@ DATA = $(NAME)u.control $(NAME)u--1.0.sql
# header files to install - it's not clear which of these might be needed
# so install them all.
INCS = plpython.h \
plpython_system.h \
plpy_cursorobject.h \
plpy_elog.h \
plpy_exec.h \
@ -120,7 +121,7 @@ install-data: installdirs
uninstall-data:
rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, plpython.h plpy_util.h)
rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, $(INCS))
.PHONY: install-data uninstall-data

View File

@ -67,6 +67,7 @@ install_headers(
'plpy_typeio.h',
'plpy_util.h',
'plpython.h',
'plpython_system.h',
install_dir: dir_include_server,
)

View File

@ -20,27 +20,10 @@
#endif
/*
* Python versions <= 3.8 otherwise define a replacement, causing macro
* redefinition warnings.
* Pull in Python headers via a wrapper header, to control the scope of
* the system_header pragma therein.
*/
#define HAVE_SNPRINTF 1
#if defined(_MSC_VER) && defined(_DEBUG)
/* Python uses #pragma to bring in a non-default libpython on VC++ if
* _DEBUG is defined */
#undef _DEBUG
/* Also hide away errcode, since we load Python.h before postgres.h */
#define errcode __msvc_errcode
#include <Python.h>
#undef errcode
#define _DEBUG
#elif defined (_MSC_VER)
#define errcode __msvc_errcode
#include <Python.h>
#undef errcode
#else
#include <Python.h>
#endif
#include "plpython_system.h"
/* define our text domain for translations */
#undef TEXTDOMAIN

View File

@ -0,0 +1,53 @@
/*-------------------------------------------------------------------------
*
* plpython_system.h - pull in Python's system header files
*
* We break this out as a separate header file to precisely control
* the scope of the "system_header" pragma. No Postgres-specific
* declarations should be put here. However, we do include some stuff
* that is meant to prevent conflicts between our code and Python.
*
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/pl/plpython/plpython_system.h
*
*-------------------------------------------------------------------------
*/
#ifndef PLPYTHON_SYSTEM_H
#define PLPYTHON_SYSTEM_H
/*
* Newer versions of the Python headers trigger a lot of warnings with our
* preferred compiler flags (at least -Wdeclaration-after-statement is known
* to be problematic). The system_header pragma hides warnings from within
* the rest of this file, if supported.
*/
#ifdef HAVE_PRAGMA_GCC_SYSTEM_HEADER
#pragma GCC system_header
#endif
/*
* Python versions <= 3.8 otherwise define a replacement, causing macro
* redefinition warnings.
*/
#define HAVE_SNPRINTF 1
#if defined(_MSC_VER) && defined(_DEBUG)
/* Python uses #pragma to bring in a non-default libpython on VC++ if
* _DEBUG is defined */
#undef _DEBUG
/* Also hide away errcode, since we load Python.h before postgres.h */
#define errcode __msvc_errcode
#include <Python.h>
#undef errcode
#define _DEBUG
#elif defined (_MSC_VER)
#define errcode __msvc_errcode
#include <Python.h>
#undef errcode
#else
#include <Python.h>
#endif
#endif /* PLPYTHON_SYSTEM_H */

View File

@ -6853,6 +6853,21 @@ on true;
Filter: (t3.id IS NOT NULL)
(8 rows)
-- Check that SJE replaces join clauses involving the removed rel correctly
explain (costs off)
select * from emp1 t1
inner join emp1 t2 on t1.id = t2.id
left join emp1 t3 on t1.id > 1 and t1.id < 2;
QUERY PLAN
----------------------------------------------
Nested Loop Left Join
Join Filter: ((t2.id > 1) AND (t2.id < 2))
-> Seq Scan on emp1 t2
Filter: (id IS NOT NULL)
-> Materialize
-> Seq Scan on emp1 t3
(6 rows)
-- We can remove the join even if we find the join can't duplicate rows and
-- the base quals of each side are different. In the following case we end up
-- moving quals over to s1 to make it so it can't match any rows.

View File

@ -2610,6 +2610,12 @@ select * from generate_series(1,10) t1(id) left join
lateral (select t1.id as t1id, t2.id from emp1 t2 join emp1 t3 on t2.id = t3.id)
on true;
-- Check that SJE replaces join clauses involving the removed rel correctly
explain (costs off)
select * from emp1 t1
inner join emp1 t2 on t1.id = t2.id
left join emp1 t3 on t1.id > 1 and t1.id < 2;
-- We can remove the join even if we find the join can't duplicate rows and
-- the base quals of each side are different. In the following case we end up
-- moving quals over to s1 to make it so it can't match any rows.